public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx
@ 2008-07-31 10:54 Guennadi Liakhovetski
  2008-07-31 14:24 ` Wolfgang Denk
  2008-07-31 19:55 ` [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 2 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-07-31 10:54 UTC (permalink / raw)
  To: u-boot

Ported from u-boot-1.1.6 driver by Samsung.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 drivers/mtd/nand/Makefile  |    1 +
 drivers/mtd/nand/s3c64xx.c |  373 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 374 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/s3c64xx.c

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 7bd22a0..236cf03 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -33,6 +33,7 @@ COBJS-y += nand_bbt.o
 COBJS-y += nand_util.o
 
 COBJS-y += fsl_upm.o
+COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c
new file mode 100644
index 0000000..49d3440
--- /dev/null
+++ b/drivers/mtd/nand/s3c64xx.c
@@ -0,0 +1,315 @@
+/*
+ * (C) Copyright 2006 DENX Software Engineering
+ *
+ * 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 <nand.h>
+#include <s3c6400.h>
+
+#include <asm/io.h>
+
+#ifdef CONFIG_NAND_SPL
+#define printf(arg...) do {} while (0)
+#endif
+
+/* Nand flash definition values by jsgood */
+#define S3C_NAND_CFG_HWECC
+#undef	S3C_NAND_DEBUG
+
+#ifdef S3C_NAND_DEBUG
+/*
+ * Function to print out oob buffer for debugging
+ * Written by jsgood
+ */
+static void print_oob(const char *header, struct mtd_info *mtd)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	printf("%s:\t", header);
+
+	for(i = 0; i < 64; i++)
+		printf("%02x ", chip->oob_poi[i]);
+
+	printf("\n");
+}
+#endif /* S3C_NAND_DEBUG */
+
+#ifdef CONFIG_NAND_SPL
+static u_char nand_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	return readb(this->IO_ADDR_R);
+}
+
+static void nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+	struct nand_chip *this = mtd->priv;
+	writeb(byte, this->IO_ADDR_W);
+}
+
+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i = 0; i < len; i++)
+		buf[i] = readb(this->IO_ADDR_R);
+}
+#endif
+
+static void s3c_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	int ctrl = readl(NFCONT);
+
+	switch (chip) {
+	case -1:
+		ctrl |= 6;
+		break;
+	case 0:
+		ctrl &= ~2;
+		break;
+	case 1:
+		ctrl &= ~4;
+		break;
+	default:
+		return;
+	}
+
+	writel(ctrl, NFCONT);
+}
+
+/*
+ * Hardware specific access to control-lines function
+ * Written by jsgood
+ */
+static void s3c_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	struct nand_chip *this = mtd->priv;
+
+	switch (cmd) {
+	case NAND_CTL_SETCLE:
+		this->IO_ADDR_W = (void __iomem *)NFCMMD;
+		break;
+	case NAND_CTL_CLRCLE:
+		this->IO_ADDR_W = (void __iomem *)NFDATA;
+		break;
+	case NAND_CTL_SETALE:
+		this->IO_ADDR_W = (void __iomem *)NFADDR;
+		break;
+	case NAND_CTL_CLRALE:
+		this->IO_ADDR_W = (void __iomem *)NFDATA;
+		break;
+	case NAND_CTL_SETNCE:
+		s3c_nand_select_chip(mtd, 0);
+		break;
+	case NAND_CTL_CLRNCE:
+		s3c_nand_select_chip(mtd, -1);
+		break;
+	}
+}
+
+/*
+ * Function for checking device ready pin
+ * Written by jsgood
+ */
+static int s3c_nand_device_ready(struct mtd_info *mtdinfo)
+{
+	while (!(readl(NFSTAT) & NFSTAT_RnB)) {}
+	return 1;
+}
+
+#ifdef S3C_NAND_CFG_HWECC
+/*
+ * This function is called before encoding ecc codes to ready ecc engine.
+ * Written by jsgood
+ */
+static void s3c_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	u_long nfcont, nfconf;
+
+	/*
+	 * The original driver used 4-bit ECC for "new" MLC chips, i.e., for
+	 * those with non-zero ID[3][3:2], which anyway only holds for ST
+	 * (Numonyx) chips
+	 */
+	nfconf = readl(NFCONF) & ~NFCONF_ECC_4BIT;
+
+	writel(nfconf, NFCONF);
+
+	/* Initialize & unlock */
+	nfcont = readl(NFCONT);
+	nfcont |= NFCONT_INITECC;
+	nfcont &= ~NFCONT_MECCLOCK;
+
+	if (mode == NAND_ECC_WRITE)
+		nfcont |= NFCONT_ECC_ENC;
+	else if (mode == NAND_ECC_READ)
+		nfcont &= ~NFCONT_ECC_ENC;
+
+	writel(nfcont, NFCONT);
+}
+
+/*
+ * This function is called immediately after encoding ecc codes.
+ * This function returns encoded ecc codes.
+ * Written by jsgood
+ */
+static int s3c_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+				  u_char *ecc_code)
+{
+	u_long nfcont, nfmecc0;
+
+	/* Lock */
+	nfcont = readl(NFCONT);
+	nfcont |= NFCONT_MECCLOCK;
+	writel(nfcont, NFCONT);
+
+	nfmecc0 = readl(NFMECC0);
+
+	ecc_code[0] = nfmecc0 & 0xff;
+	ecc_code[1] = (nfmecc0 >> 8) & 0xff;
+	ecc_code[2] = (nfmecc0 >> 16) & 0xff;
+	ecc_code[3] = (nfmecc0 >> 24) & 0xff;
+
+	return 0;
+}
+
+/*
+ * This function determines whether read data is good or not.
+ * If SLC, must write ecc codes to controller before reading status bit.
+ * If MLC, status bit is already set, so only reading is needed.
+ * If status bit is good, return 0.
+ * If correctable errors occured, do that.
+ * If uncorrectable errors occured, return -1.
+ * Written by jsgood
+ */
+static int s3c_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+				 u_char *read_ecc, u_char *calc_ecc)
+{
+	int ret = -1;
+	u_long nfestat0, nfmeccdata0, nfmeccdata1;
+	u_char err_type;
+
+	/* SLC: Write ecc to compare */
+	nfmeccdata0 = (calc_ecc[1] << 16) | calc_ecc[0];
+	nfmeccdata1 = (calc_ecc[3] << 16) | calc_ecc[2];
+	writel(nfmeccdata0, NFMECCDATA0);
+	writel(nfmeccdata1, NFMECCDATA1);
+
+	/* Read ecc status */
+	nfestat0 = readl(NFESTAT0);
+	err_type = nfestat0 & 0x3;
+
+	switch (err_type) {
+	case 0: /* No error */
+		ret = 0;
+		break;
+
+	case 1: /* 1 bit error (Correctable)
+		   (nfestat0 >> 7) & 0x7ff	:error byte number
+		   (nfestat0 >> 4) & 0x7	:error bit number */
+		printf("S3C NAND: 1 bit error detected at byte %ld. Correcting from "
+		       "0x%02x ", (nfestat0 >> 7) & 0x7ff, dat[(nfestat0 >> 7) & 0x7ff]);
+		dat[(nfestat0 >> 7) & 0x7ff] ^= (1 << ((nfestat0 >> 4) & 0x7));
+		printf("to 0x%02x...OK\n", dat[(nfestat0 >> 7) & 0x7ff]);
+		ret = 1;
+		break;
+
+	case 2: /* Multiple error */
+	case 3: /* ECC area error */
+		printf("S3C NAND: ECC uncorrectable error detected. Not correctable.\n");
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+#endif /* S3C_NAND_CFG_HWECC */
+
+/*
+ * Board-specific NAND initialization. The following members of the
+ * argument are board-specific (per include/linux/mtd/nand.h):
+ * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
+ * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
+ * - hwcontrol: hardwarespecific function for accesing control-lines
+ * - dev_ready: hardwarespecific function for  accesing device ready/busy line
+ * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
+ *   only be provided if a hardware ECC is available
+ * - eccmode: mode of ecc, see defines
+ * - chip_delay: chip dependent delay for transfering data from array to
+ *   read regs (tR)
+ * - options: various chip options. They can partly be set to inform
+ *   nand_scan about special functionality. See the defines for further
+ *   explanation
+ * Members with a "?" were not set in the merged testing-NAND branch,
+ * so they are not set here either.
+ */
+#include <linux/mtd/mtd.h>
+int board_nand_init(struct nand_chip *nand)
+{
+	NFCONT_REG 		= (NFCONT_REG & ~NFCONT_WP) | NFCONT_ENABLE | 0x6;
+
+	nand->IO_ADDR_R		= (void __iomem *)NFDATA;
+	nand->IO_ADDR_W		= (void __iomem *)NFDATA;
+	nand->hwcontrol		= s3c_nand_hwcontrol;
+	nand->dev_ready		= s3c_nand_device_ready;
+	nand->select_chip	= s3c_nand_select_chip;
+	nand->options		= 0;
+#ifdef CONFIG_NAND_SPL
+	nand->read_byte		= nand_read_byte;
+	nand->write_byte	= nand_write_byte;
+	nand->read_buf		= nand_read_buf;
+#endif
+
+	do {
+		struct mtd_info m;
+		int cellinfo;
+
+		m.priv = nand;
+
+		s3c_nand_select_chip(&m, 0);
+		s3c_nand_hwcontrol(&m, NAND_CTL_SETCLE);
+		writeb(NAND_CMD_READID, nand->IO_ADDR_W);
+		s3c_nand_hwcontrol(&m, NAND_CTL_CLRCLE);
+		s3c_nand_device_ready(&m);
+		cellinfo = readb(nand->IO_ADDR_R);
+		cellinfo += readb(nand->IO_ADDR_R);
+		cellinfo += readb(nand->IO_ADDR_R);
+		s3c_nand_select_chip(&m, -1);
+		nand->eccmode = cellinfo;
+	} while (0);
+
+#ifdef S3C_NAND_CFG_HWECC
+	nand->enable_hwecc	= s3c_nand_enable_hwecc;
+	nand->calculate_ecc	= s3c_nand_calculate_ecc;
+	nand->correct_data	= s3c_nand_correct_data;
+
+	/* A shot in the dark, I don't know how to use this smart ECC-mode
+	 * selection with the current driver */
+	nand->eccmode		= NAND_ECC_HW12_2048;
+#else
+	nand->eccmode		= NAND_ECC_SOFT;
+#endif /* ! S3C_NAND_CFG_HWECC */
+
+	return 0;
+}

-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx
  2008-07-31 10:54 [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
@ 2008-07-31 14:24 ` Wolfgang Denk
  2008-08-01 11:02   ` Guennadi Liakhovetski
  2008-07-31 19:55 ` [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 1 reply; 36+ messages in thread
From: Wolfgang Denk @ 2008-07-31 14:24 UTC (permalink / raw)
  To: u-boot

In message <Pine.LNX.4.64.0807311246100.4832@axis700.grange> you wrote:
> Ported from u-boot-1.1.6 driver by Samsung.
> 
> Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
...

> --- /dev/null
> +++ b/drivers/mtd/nand/s3c64xx.c
> @@ -0,0 +1,315 @@
> +/*
> + * (C) Copyright 2006 DENX Software Engineering

Please add your name here.

> +/*
> + * Function to print out oob buffer for debugging
> + * Written by jsgood

Then jsgood should be mentioned in the (C) lines?

> +	case 1: /* 1 bit error (Correctable)
> +		   (nfestat0 >> 7) & 0x7ff	:error byte number
> +		   (nfestat0 >> 4) & 0x7	:error bit number */
> +		printf("S3C NAND: 1 bit error detected at byte %ld. Correcting from "
> +		       "0x%02x ", (nfestat0 >> 7) & 0x7ff, dat[(nfestat0 >> 7) & 0x7ff]);
> +		dat[(nfestat0 >> 7) & 0x7ff] ^= (1 << ((nfestat0 >> 4) & 0x7));
> +		printf("to 0x%02x...OK\n", dat[(nfestat0 >> 7) & 0x7ff]);

I guess there should be a way to write this code so  it  is  actually
readable?  This  is  U-Boot,  not  the  IOCCC  (yes,  there *is* some
difference, still).

> +int board_nand_init(struct nand_chip *nand)
> +{
> +	NFCONT_REG 		= (NFCONT_REG & ~NFCONT_WP) | NFCONT_ENABLE | 0x6;
> +
> +	nand->IO_ADDR_R		= (void __iomem *)NFDATA;
> +	nand->IO_ADDR_W		= (void __iomem *)NFDATA;
> +	nand->hwcontrol		= s3c_nand_hwcontrol;
> +	nand->dev_ready		= s3c_nand_device_ready;
> +	nand->select_chip	= s3c_nand_select_chip;
> +	nand->options		= 0;
> +#ifdef CONFIG_NAND_SPL
> +	nand->read_byte		= nand_read_byte;
> +	nand->write_byte	= nand_write_byte;
> +	nand->read_buf		= nand_read_buf;
> +#endif
> +
> +	do {
> +		struct mtd_info m;
> +		int cellinfo;
> +
> +		m.priv = nand;
> +
> +		s3c_nand_select_chip(&m, 0);
> +		s3c_nand_hwcontrol(&m, NAND_CTL_SETCLE);
> +		writeb(NAND_CMD_READID, nand->IO_ADDR_W);
> +		s3c_nand_hwcontrol(&m, NAND_CTL_CLRCLE);
> +		s3c_nand_device_ready(&m);
> +		cellinfo = readb(nand->IO_ADDR_R);
> +		cellinfo += readb(nand->IO_ADDR_R);
> +		cellinfo += readb(nand->IO_ADDR_R);
> +		s3c_nand_select_chip(&m, -1);
> +		nand->eccmode = cellinfo;
> +	} while (0);

Please get rid of the do...while here - or does it serve any purpose?

> +	/* A shot in the dark, I don't know how to use this smart ECC-mode
> +	 * selection with the current driver */

Incorrect multiline comment style.

Please check other files for that, too.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Once upon a time, "PC" meant "personal computer".  Now  it  seems  to
only  mean  "Prisoner  of Bill". Alas! All my PCs run Unix, and those
include Intel, Sparc, and other processors.
          -- Tom "Bring back the non-PC meaning of `PC'" Christiansen

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx
  2008-07-31 10:54 [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
  2008-07-31 14:24 ` Wolfgang Denk
@ 2008-07-31 19:55 ` Jean-Christophe PLAGNIOL-VILLARD
  1 sibling, 0 replies; 36+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2008-07-31 19:55 UTC (permalink / raw)
  To: u-boot

> +/*
> + * (C) Copyright 2006 DENX Software Engineering
> + *
> + * 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 <nand.h>
> +#include <s3c6400.h>
> +
> +#include <asm/io.h>
> +
> +#ifdef CONFIG_NAND_SPL
> +#define printf(arg...) do {} while (0)
> +#endif
> +
> +/* Nand flash definition values by jsgood */
> +#define S3C_NAND_CFG_HWECC
Please move to config file
> +#undef	S3C_NAND_DEBUG
please remove
> +
> +#ifdef S3C_NAND_DEBUG
> +/*
> + * Function to print out oob buffer for debugging
> + * Written by jsgood
> + */
> +static void print_oob(const char *header, struct mtd_info *mtd)
> +{
> +	int i;
> +	struct nand_chip *chip = mtd->priv;
> +
> +	printf("%s:\t", header);
> +
> +	for(i = 0; i < 64; i++)
> +		printf("%02x ", chip->oob_poi[i]);
> +
> +	printf("\n");
> +}
> +#endif /* S3C_NAND_DEBUG */
> +
> +#ifdef CONFIG_NAND_SPL
> +static u_char nand_read_byte(struct mtd_info *mtd)
> +{
> +	struct nand_chip *this = mtd->priv;
add an empty line
> +	return readb(this->IO_ADDR_R);
> +}
> +
> +static void nand_write_byte(struct mtd_info *mtd, u_char byte)
> +{
> +	struct nand_chip *this = mtd->priv;
add an empty line
> +	writeb(byte, this->IO_ADDR_W);
> +}
> +
> +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
> +{
> +	int i;
> +	struct nand_chip *this = mtd->priv;
> +
> +	for (i = 0; i < len; i++)
> +		buf[i] = readb(this->IO_ADDR_R);
> +}
> +#endif
> +
> +/*
> + * This function determines whether read data is good or not.
> + * If SLC, must write ecc codes to controller before reading status bit.
> + * If MLC, status bit is already set, so only reading is needed.
> + * If status bit is good, return 0.
> + * If correctable errors occured, do that.
> + * If uncorrectable errors occured, return -1.
> + * Written by jsgood
> + */
> +static int s3c_nand_correct_data(struct mtd_info *mtd, u_char *dat,
> +				 u_char *read_ecc, u_char *calc_ecc)
> +{
> +	int ret = -1;
> +	u_long nfestat0, nfmeccdata0, nfmeccdata1;
> +	u_char err_type;
> +
> +	/* SLC: Write ecc to compare */
> +	nfmeccdata0 = (calc_ecc[1] << 16) | calc_ecc[0];
> +	nfmeccdata1 = (calc_ecc[3] << 16) | calc_ecc[2];
> +	writel(nfmeccdata0, NFMECCDATA0);
> +	writel(nfmeccdata1, NFMECCDATA1);
> +
> +	/* Read ecc status */
> +	nfestat0 = readl(NFESTAT0);
> +	err_type = nfestat0 & 0x3;
> +
> +	switch (err_type) {
> +	case 0: /* No error */
> +		ret = 0;
> +		break;
> +
> +	case 1: /* 1 bit error (Correctable)
> +		   (nfestat0 >> 7) & 0x7ff	:error byte number
> +		   (nfestat0 >> 4) & 0x7	:error bit number */
> +		printf("S3C NAND: 1 bit error detected at byte %ld. Correcting from "
> +		       "0x%02x ", (nfestat0 >> 7) & 0x7ff, dat[(nfestat0 >> 7) & 0x7ff]);
> +		dat[(nfestat0 >> 7) & 0x7ff] ^= (1 << ((nfestat0 >> 4) & 0x7));
> +		printf("to 0x%02x...OK\n", dat[(nfestat0 >> 7) & 0x7ff]);
could use inline or macro to be more readable
> +		ret = 1;
> +		break;
> +
> +	case 2: /* Multiple error */
> +	case 3: /* ECC area error */
> +		printf("S3C NAND: ECC uncorrectable error detected. Not correctable.\n");
> +		ret = -1;
> +		break;
> +	}
> +
> +	return ret;
> +}
> +#endif /* S3C_NAND_CFG_HWECC */
> +
> +/*
> + * Board-specific NAND initialization. The following members of the
> + * argument are board-specific (per include/linux/mtd/nand.h):
> + * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
> + * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
> + * - hwcontrol: hardwarespecific function for accesing control-lines
> + * - dev_ready: hardwarespecific function for  accesing device ready/busy line
> + * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
> + *   only be provided if a hardware ECC is available
> + * - eccmode: mode of ecc, see defines
> + * - chip_delay: chip dependent delay for transfering data from array to
> + *   read regs (tR)
> + * - options: various chip options. They can partly be set to inform
> + *   nand_scan about special functionality. See the defines for further
> + *   explanation
> + * Members with a "?" were not set in the merged testing-NAND branch,
> + * so they are not set here either.
> + */
> +#include <linux/mtd/mtd.h>
move to the top
> +int board_nand_init(struct nand_chip *nand)
> +{
> +	NFCONT_REG 		= (NFCONT_REG & ~NFCONT_WP) | NFCONT_ENABLE | 0x6;
> +
> +	nand->IO_ADDR_R		= (void __iomem *)NFDATA;
> +	nand->IO_ADDR_W		= (void __iomem *)NFDATA;
> +	nand->hwcontrol		= s3c_nand_hwcontrol;
> +	nand->dev_ready		= s3c_nand_device_ready;
> +	nand->select_chip	= s3c_nand_select_chip;
> +	nand->options		= 0;

Best Regards,
J.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx
  2008-07-31 14:24 ` Wolfgang Denk
@ 2008-08-01 11:02   ` Guennadi Liakhovetski
  2008-08-01 12:28     ` Wolfgang Denk
  0 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-01 11:02 UTC (permalink / raw)
  To: u-boot

On Thu, 31 Jul 2008, Wolfgang Denk wrote:

> > --- /dev/null
> > +++ b/drivers/mtd/nand/s3c64xx.c
> > @@ -0,0 +1,315 @@
> > +/*
> > + * (C) Copyright 2006 DENX Software Engineering
> 
> Please add your name here.

I will add my copyright in a couple of files, but I would rather not add 
it to Makefiles. Below I quote an earlier post on this list (funnily, I 
wasn't able to get it in sourceforge's archive...), which addresses 
Copyrights in Makefiles. To me it sounds reasonable, because in my example 
I really added very little "IP" to it, almost exclusively copy-paste from 
other Makefiles. What I learned, is one may never delete copyrights from 
files, ones they are there, that's why I preserved yours - that's how this 
file was in Samsung's version. But I don't think my Copyright there will 
serve any good purpose.

> > +/*
> > + * Function to print out oob buffer for debugging
> > + * Written by jsgood
> 
> Then jsgood should be mentioned in the (C) lines?

Is it allowed to add other peaople's copyright without their consent?

I am working on the rest comments... cleaning up others' mess.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

###################################
########### QUOTED MAIL ###########
###################################

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx
  2008-08-01 11:02   ` Guennadi Liakhovetski
@ 2008-08-01 12:28     ` Wolfgang Denk
  2008-08-01 13:30       ` [U-Boot-Users] several messages Guennadi Liakhovetski
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
  0 siblings, 2 replies; 36+ messages in thread
From: Wolfgang Denk @ 2008-08-01 12:28 UTC (permalink / raw)
  To: u-boot

In message <Pine.LNX.4.64.0808011231520.14927@axis700.grange> you wrote:
> 
> > > + * (C) Copyright 2006 DENX Software Engineering
> > 
> > Please add your name here.
> 
> I will add my copyright in a couple of files, but I would rather not add 
> it to Makefiles. Below I quote an earlier post on this list (funnily, I 

Note that in the case you quoted my request was that you  add  *your*
name,  not  only  that  of  our company. This is Free Software, and I
consider you the copyright owner. I  am  aware  that  in  many  other
companies  you  have  to  sign  contracts that all such rights belong
exclusively to the company, but DENX doesn't do that.

> > > + * Function to print out oob buffer for debugging
> > > + * Written by jsgood
> > 
> > Then jsgood should be mentioned in the (C) lines?
> 
> Is it allowed to add other peaople's copyright without their consent?

No, you cannot do that without asking him. Maybe you find his address
somewhere?

> I am working on the rest comments... cleaning up others' mess.

That was your job in that project, wasn't it? ;-)

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Every program has at least one bug and can be shortened by  at  least
one instruction - from which, by induction, one can deduce that every
program can be reduced to one instruction which doesn't work.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] several messages
  2008-08-01 12:28     ` Wolfgang Denk
@ 2008-08-01 13:30       ` Guennadi Liakhovetski
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
  1 sibling, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-01 13:30 UTC (permalink / raw)
  To: u-boot

On Fri, 1 Aug 2008, Wolfgang Denk wrote:

> In message <Pine.LNX.4.64.0808011231520.14927@axis700.grange> you wrote:
> > 
> > > > + * (C) Copyright 2006 DENX Software Engineering
> > > 
> > > Please add your name here.
> > 
> > I will add my copyright in a couple of files, but I would rather not add 
> > it to Makefiles. Below I quote an earlier post on this list (funnily, I 
> 
> Note that in the case you quoted my request was that you  add  *your*
> name,  not  only  that  of  our company. This is Free Software, and I
> consider you the copyright owner. I  am  aware  that  in  many  other
> companies  you  have  to  sign  contracts that all such rights belong
> exclusively to the company, but DENX doesn't do that.

You mean insert my name in that line? But I haven't had anything to do 
with this file in 2006:-) This is an old line from Samsung sources. I 
thought your request above was the same as this one:

On Thu, 31 Jul 2008, Wolfgang Denk wrote:

> > diff --git a/board/samsung/smdk6400/Makefile b/board/samsung/smdk6400/Makefile
> > new file mode 100644
> > index 0000000..1200e45
> > --- /dev/null
> > +++ b/board/samsung/smdk6400/Makefile
> > @@ -0,0 +1,51 @@
> > +#
> > +# (C) Copyright 2000, 2001, 2002
> > +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> 
> Who contributed more to this Makefile - you or me?

and you wanted me to _add_ my copyright to existing ones. And that is what 
I wasn't specifically keen on in case of Makefiles:-)

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support
  2008-08-01 12:28     ` Wolfgang Denk
  2008-08-01 13:30       ` [U-Boot-Users] several messages Guennadi Liakhovetski
@ 2008-08-04 10:42       ` Guennadi Liakhovetski
  2008-08-04 10:42         ` [U-Boot-Users] [PATCH 1/7 v2] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
                           ` (8 more replies)
  1 sibling, 9 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:42 UTC (permalink / raw)
  To: u-boot

Hi,

this is version 2 of the smdk6400 patch series. I hope, I took care of all
comments, apart of these ones:

On Thu, 31 Jul 2008, Jean-Christophe PLAGNIOL-VILLARD wrote:

> > +#ifdef CONFIG_NAND_SPL
> > +static u_char nand_read_byte(struct mtd_info *mtd)
> > +{
> > +   struct nand_chip *this = mtd->priv;
> add an empty line
> > +   return readb(this->IO_ADDR_R);
> > +}
> > +
> > +static void nand_write_byte(struct mtd_info *mtd, u_char byte)
> > +{
> > +   struct nand_chip *this = mtd->priv;
> add an empty line
> > +   writeb(byte, this->IO_ADDR_W);
> > +}

Sorry, looks like a matter of taste to me. There are also very few lines 
over 80 characters left, but fixing them would look too awkward...

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 1/7 v2] Add definition for the AM29LV800BB AMD NOR-flash
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
@ 2008-08-04 10:42         ` Guennadi Liakhovetski
  2008-08-04 10:42         ` [U-Boot-Users] [PATCH 2/7 v2] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead Guennadi Liakhovetski
                           ` (7 subsequent siblings)
  8 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:42 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 drivers/mtd/jedec_flash.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/jedec_flash.c b/drivers/mtd/jedec_flash.c
index 9845e93..020647a 100644
--- a/drivers/mtd/jedec_flash.c
+++ b/drivers/mtd/jedec_flash.c
@@ -234,6 +234,23 @@ static const struct amd_flash_info jedec_table[] = {
 			ERASEINFO(0x10000,7),
 		}
 	},
+	{
+		.mfr_id		= MANUFACTURER_AMD,
+		.dev_id		= AM29LV800BB,
+		.name		= "AMD AM29LV800BB",
+		.uaddr		= {
+			[1] = MTD_UADDR_0x0555_0x02AA /* x16 */
+		},
+		.DevSize	= SIZE_1MiB,
+		.CmdSet		= CFI_CMDSET_AMD_LEGACY,
+		.NumEraseRegions= 4,
+		.regions	= {
+			ERASEINFO(0x04000, 1),
+			ERASEINFO(0x02000, 2),
+			ERASEINFO(0x08000, 1),
+			ERASEINFO(0x10000, 15),
+		}
+	},
 #endif
 };
 
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 2/7 v2] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
  2008-08-04 10:42         ` [U-Boot-Users] [PATCH 1/7 v2] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
@ 2008-08-04 10:42         ` Guennadi Liakhovetski
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 3/7 v2] ARM: Add arm1176 core with s3c6400 SoC Guennadi Liakhovetski
                           ` (6 subsequent siblings)
  8 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:42 UTC (permalink / raw)
  To: u-boot

I _think_ this should work with all NAND chips. Otherwise we might have to 
introduce a configuration variable.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 nand_spl/nand_boot.c |   61 +++++++++++++++++++++++++------------------------
 1 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c
index 563a80b..78eaf75 100644
--- a/nand_spl/nand_boot.c
+++ b/nand_spl/nand_boot.c
@@ -128,21 +128,6 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8
 }
 #endif
 
-static int nand_is_bad_block(struct mtd_info *mtd, int block)
-{
-	struct nand_chip *this = mtd->priv;
-
-	nand_command(mtd, block, 0, CFG_NAND_BAD_BLOCK_POS, NAND_CMD_READOOB);
-
-	/*
-	 * Read one byte
-	 */
-	if (this->read_byte(mtd) != 0xff)
-		return 1;
-
-	return 0;
-}
-
 static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 {
 	struct nand_chip *this = mtd->priv;
@@ -150,8 +135,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 	u_char *ecc_code;
 	u_char *oob_data;
 	int i;
-	int eccsize = CFG_NAND_ECCSIZE;
-	int eccbytes = CFG_NAND_ECCBYTES;
 	int eccsteps = CFG_NAND_ECCSTEPS;
 	uint8_t *p = dst;
 	int stat;
@@ -163,11 +146,11 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 	 */
 	ecc_calc = (u_char *)(CFG_SDRAM_BASE + 0x10000);
 	ecc_code = ecc_calc + 0x100;
-	oob_data = ecc_calc + 0x200;
+	oob_data = p + CFG_NAND_PAGE_SIZE; /* Append OOB to the page data */
 
-	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+	for (i = 0; eccsteps; eccsteps--, i += CFG_NAND_ECCBYTES, p += CFG_NAND_ECCSIZE) {
 		this->enable_hwecc(mtd, NAND_ECC_READ);
-		this->read_buf(mtd, p, eccsize);
+		this->read_buf(mtd, p, CFG_NAND_ECCSIZE);
 		this->calculate_ecc(mtd, p, &ecc_calc[i]);
 	}
 	this->read_buf(mtd, oob_data, CFG_NAND_OOBSIZE);
@@ -179,7 +162,7 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 	eccsteps = CFG_NAND_ECCSTEPS;
 	p = dst;
 
-	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+	for (i = 0; eccsteps; eccsteps--, i += CFG_NAND_ECCBYTES, p += CFG_NAND_ECCSIZE) {
 		/* No chance to do something with the possible error message
 		 * from correct_data(). We just hope that all possible errors
 		 * are corrected by this routine.
@@ -195,6 +178,7 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst)
 	int block;
 	int blockcopy_count;
 	int page;
+	unsigned read = 0;
 
 	/*
 	 * offs has to be aligned to a block address!
@@ -202,18 +186,29 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst)
 	block = offs / CFG_NAND_BLOCK_SIZE;
 	blockcopy_count = 0;
 
-	while (blockcopy_count < (uboot_size / CFG_NAND_BLOCK_SIZE)) {
-		if (!nand_is_bad_block(mtd, block)) {
-			/*
-			 * Skip bad blocks
-			 */
-			for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) {
-				nand_read_page(mtd, block, page, dst);
-				dst += CFG_NAND_PAGE_SIZE;
+	while (blockcopy_count < ((uboot_size + CFG_NAND_BLOCK_SIZE - 1) / CFG_NAND_BLOCK_SIZE)) {
+		/*
+		 * Skip bad blocks
+		 */
+		int badblock = 0;
+		for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) {
+			nand_read_page(mtd, block, page, dst);
+			if ((!page
+#ifdef CFG_NAND_BBT_2NDPAGE
+			     || page == 1
+#endif
+				    ) && dst[CFG_NAND_PAGE_SIZE] != 0xff) {
+				badblock = 1;
+				break;
 			}
+			/* Overwrite skipped pages */
+			if (read >= offs)
+				dst += CFG_NAND_PAGE_SIZE;
+			read += CFG_NAND_PAGE_SIZE;
+		}
 
+		if (!badblock)
 			blockcopy_count++;
-		}
 
 		block++;
 	}
@@ -241,12 +236,18 @@ void nand_boot(void)
 	nand_chip.dev_ready = NULL;	/* preset to NULL */
 	board_nand_init(&nand_chip);
 
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&nand_info, 0);
+
 	/*
 	 * Load U-Boot image from NAND into RAM
 	 */
 	ret = nand_load(&nand_info, CFG_NAND_U_BOOT_OFFS, CFG_NAND_U_BOOT_SIZE,
 			(uchar *)CFG_NAND_U_BOOT_DST);
 
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&nand_info, -1);
+
 	/*
 	 * Jump to U-Boot image
 	 */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 3/7 v2] ARM: Add arm1176 core with s3c6400 SoC
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
  2008-08-04 10:42         ` [U-Boot-Users] [PATCH 1/7 v2] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
  2008-08-04 10:42         ` [U-Boot-Users] [PATCH 2/7 v2] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead Guennadi Liakhovetski
@ 2008-08-04 10:43         ` Guennadi Liakhovetski
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 4/7 v2] USB: Add support for OHCI controller on s3c6400 Guennadi Liakhovetski
                           ` (5 subsequent siblings)
  8 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:43 UTC (permalink / raw)
  To: u-boot

This is a port of s3c6400 sources by Samsung from u-boot-1.1.6.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 cpu/arm1176/Makefile                    |   50 ++
 cpu/arm1176/config.mk                   |   35 ++
 cpu/arm1176/cpu.c                       |  189 +++++++
 cpu/arm1176/s3c64xx/Makefile            |   48 ++
 cpu/arm1176/s3c64xx/config.mk           |   34 ++
 cpu/arm1176/s3c64xx/cpu_init.S          |  142 +++++
 cpu/arm1176/s3c64xx/interrupts.c        |  278 ++++++++++
 cpu/arm1176/s3c64xx/speed.c             |  140 +++++
 cpu/arm1176/start.S                     |  469 +++++++++++++++++
 include/asm-arm/arch-s3c64xx/hardware.h |   63 +++
 include/common.h                        |    3 +-
 include/s3c6400.h                       |  866 +++++++++++++++++++++++++++++++
 include/s3c64x0.h                       |   92 ++++
 13 files changed, 2408 insertions(+), 1 deletions(-)
 create mode 100644 cpu/arm1176/Makefile
 create mode 100644 cpu/arm1176/config.mk
 create mode 100644 cpu/arm1176/cpu.c
 create mode 100644 cpu/arm1176/s3c64xx/Makefile
 create mode 100644 cpu/arm1176/s3c64xx/config.mk
 create mode 100644 cpu/arm1176/s3c64xx/cpu_init.S
 create mode 100644 cpu/arm1176/s3c64xx/interrupts.c
 create mode 100644 cpu/arm1176/s3c64xx/speed.c
 create mode 100644 cpu/arm1176/start.S
 create mode 100644 include/asm-arm/arch-s3c64xx/hardware.h
 create mode 100644 include/s3c6400.h
 create mode 100644 include/s3c64x0.h

diff --git a/cpu/arm1176/Makefile b/cpu/arm1176/Makefile
new file mode 100644
index 0000000..1ca9199
--- /dev/null
+++ b/cpu/arm1176/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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$(CPU).a
+
+START	= start.o
+COBJS	= cpu.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk
new file mode 100644
index 0000000..5083594
--- /dev/null
+++ b/cpu/arm1176/config.mk
@@ -0,0 +1,35 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@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
+#
+PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
+	-msoft-float
+
+# Make ARMv5 to allow more compilers to work, even though its v6.
+PLATFORM_CPPFLAGS += -march=armv5t
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c
new file mode 100644
index 0000000..a0a9268
--- /dev/null
+++ b/cpu/arm1176/cpu.c
@@ -0,0 +1,189 @@
+/*
+ * (C) Copyright 2004 Texas Insturments
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <s3c6400.h>
+
+static void cache_flush (void);
+
+/* read co-processor 15, register #1 (control register) */
+static unsigned long read_p15_c1 (void)
+{
+	unsigned long value;
+
+	__asm__ __volatile__(
+		"mrc	p15, 0, %0, c1, c0, 0   @ read control reg\n"
+		: "=r" (value)
+		:
+		: "memory");
+	return value;
+}
+
+/* write to co-processor 15, register #1 (control register) */
+static void write_p15_c1 (unsigned long value)
+{
+	__asm__ __volatile__(
+		"mcr	p15, 0, %0, c1, c0, 0   @ write it back\n"
+		:
+		: "r" (value)
+		: "memory");
+
+	read_p15_c1();
+}
+
+static void cp_delay (void)
+{
+	volatile int i;
+
+	/* Many OMAP regs need at least 2 nops  */
+	for (i = 0; i < 100; i++)
+		__asm__ __volatile__("nop\n");
+}
+
+/* See also ARM Ref. Man. */
+#define C1_MMU		(1 << 0)	/* mmu off/on */
+#define C1_ALIGN	(1 << 1)	/* alignment faults off/on */
+#define C1_DC		(1 << 2)	/* dcache off/on */
+#define C1_WB		(1 << 3)	/* merging write buffer on/off */
+#define C1_BIG_ENDIAN	(1 << 7)	/* big endian off/on */
+#define C1_SYS_PROT	(1 << 8)	/* system protection */
+#define C1_ROM_PROT	(1 << 9)	/* ROM protection */
+#define C1_IC		(1 << 12)	/* icache off/on */
+#define C1_HIGH_VECTORS	(1 << 13)	/* location of vectors: low/high */
+#define RESERVED_1	(0xf << 3)	/* must be 111b for R/W */
+
+int cpu_init (void)
+{
+	return 0;
+}
+
+int cleanup_before_linux (void)
+{
+	/*
+	 * this function is called just before we call linux
+	 * it prepares the processor for linux
+	 *
+	 * we turn off caches etc ...
+	 */
+
+	disable_interrupts ();
+
+	/* turn off I/D-cache */
+	icache_disable();
+	dcache_disable();
+	cache_flush();
+
+	return 0;
+}
+
+
+/* * reset the cpu by setting up the watchdog timer and let him time out */
+void reset_cpu (ulong ignored)
+{
+	printf("reset... \n\n\n");
+	SW_RST_REG = 0x6400;
+	/* loop forever and wait for reset to happen */
+	while (1) {
+		if (serial_tstc()) {
+			serial_getc();
+			break;
+		}
+	}
+	/*NOTREACHED*/
+}
+
+int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	disable_interrupts ();
+	reset_cpu (0);
+	/*NOTREACHED*/
+	return 0;
+}
+
+void icache_enable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();	/* get control reg. */
+	cp_delay ();
+	write_p15_c1 (reg | C1_IC);
+}
+
+void icache_disable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	write_p15_c1 (reg & ~C1_IC);
+}
+
+int icache_status (void)
+{
+	return (read_p15_c1 () & C1_IC) != 0;
+}
+
+/* It makes no sense to use the dcache if the MMU is not enabled */
+void dcache_enable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	write_p15_c1 (reg | C1_DC);
+}
+
+void dcache_disable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	reg &= ~C1_DC;
+	write_p15_c1 (reg);
+}
+
+int dcache_status (void)
+{
+	return (read_p15_c1 () & C1_DC) != 0;
+}
+
+/* flush I/D-cache */
+static void cache_flush (void)
+{
+	/* invalidate both caches and flush btb */
+	asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0));
+	/* mem barrier to sync things */
+	asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0));
+}
diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile
new file mode 100644
index 0000000..fa4ee3f
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/Makefile
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS-y	= interrupts.o
+COBJS-$(CONFIG_S3C6400)	+= cpu_init.o speed.o
+
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk
new file mode 100644
index 0000000..204e880
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@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
+#
+PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
+	-msoft-float
+
+# Make ARMv5 to allow more compilers to work, even though its v6.
+PLATFORM_CPPFLAGS += -march=armv5t
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/s3c64xx/cpu_init.S b/cpu/arm1176/s3c64xx/cpu_init.S
new file mode 100644
index 0000000..08bda99
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/cpu_init.S
@@ -0,0 +1,142 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <config.h>
+#include <s3c6400.h>
+
+	.globl mem_ctrl_asm_init
+mem_ctrl_asm_init:
+	/* Memory subsystem address 0x7e00f120 */
+	ldr	r0, =ELFIN_MEM_SYS_CFG
+
+	/* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
+	mov	r1, #0xd
+	str	r1, [r0]
+
+	/* DMC1 base address 0x7e001000 */
+	ldr	r0, =ELFIN_DMC1_BASE
+
+	ldr	r1, =0x4
+	str	r1, [r0, #INDEX_DMC_MEMC_CMD]
+
+	ldr	r1, =DMC_DDR_REFRESH_PRD
+	str	r1, [r0, #INDEX_DMC_REFRESH_PRD]
+
+	ldr	r1, =DMC_DDR_CAS_LATENCY
+	str	r1, [r0, #INDEX_DMC_CAS_LATENCY]
+
+	ldr	r1, =DMC_DDR_t_DQSS
+	str	r1, [r0, #INDEX_DMC_T_DQSS]
+
+	ldr	r1, =DMC_DDR_t_MRD
+	str	r1, [r0, #INDEX_DMC_T_MRD]
+
+	ldr	r1, =DMC_DDR_t_RAS
+	str	r1, [r0, #INDEX_DMC_T_RAS]
+
+	ldr	r1, =DMC_DDR_t_RC
+	str	r1, [r0, #INDEX_DMC_T_RC]
+
+	ldr	r1, =DMC_DDR_t_RCD
+	ldr	r2, =DMC_DDR_schedule_RCD
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RCD]
+
+	ldr	r1, =DMC_DDR_t_RFC
+	ldr	r2, =DMC_DDR_schedule_RFC
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RFC]
+
+	ldr	r1, =DMC_DDR_t_RP
+	ldr	r2, =DMC_DDR_schedule_RP
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RP]
+
+	ldr	r1, =DMC_DDR_t_RRD
+	str	r1, [r0, #INDEX_DMC_T_RRD]
+
+	ldr	r1, =DMC_DDR_t_WR
+	str	r1, [r0, #INDEX_DMC_T_WR]
+
+	ldr	r1, =DMC_DDR_t_WTR
+	str	r1, [r0, #INDEX_DMC_T_WTR]
+
+	ldr	r1, =DMC_DDR_t_XP
+	str	r1, [r0, #INDEX_DMC_T_XP]
+
+	ldr	r1, =DMC_DDR_t_XSR
+	str	r1, [r0, #INDEX_DMC_T_XSR]
+
+	ldr	r1, =DMC_DDR_t_ESR
+	str	r1, [r0, #INDEX_DMC_T_ESR]
+
+	ldr	r1, =DMC1_MEM_CFG
+	str	r1, [r0, #INDEX_DMC_MEMORY_CFG]
+
+	ldr	r1, =DMC1_MEM_CFG2
+	str	r1, [r0, #INDEX_DMC_MEMORY_CFG2]
+
+	ldr	r1, =DMC1_CHIP0_CFG
+	str	r1, [r0, #INDEX_DMC_CHIP_0_CFG]
+
+	ldr	r1, =DMC_DDR_32_CFG
+	str	r1, [r0, #INDEX_DMC_USER_CONFIG]
+
+	/* DMC0 DDR Chip 0 configuration direct command reg */
+	ldr	r1, =DMC_NOP0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Precharge All */
+	ldr	r1, =DMC_PA0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Auto Refresh 2 time */
+	ldr	r1, =DMC_AR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* MRS */
+	ldr	r1, =DMC_mDDR_EMR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Mode Reg */
+	ldr	r1, =DMC_mDDR_MR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Enable DMC1 */
+	mov	r1, #0x0
+	str	r1, [r0, #INDEX_DMC_MEMC_CMD]
+
+check_dmc1_ready:
+	ldr	r1, [r0, #INDEX_DMC_MEMC_STATUS]
+	mov	r2, #0x3
+	and	r1, r1, r2
+	cmp	r1, #0x1
+	bne	check_dmc1_ready
+	nop
+
+	mov	pc, lr
+
+	.ltorg
diff --git a/cpu/arm1176/s3c64xx/interrupts.c b/cpu/arm1176/s3c64xx/interrupts.c
new file mode 100644
index 0000000..1c63b59
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/interrupts.c
@@ -0,0 +1,278 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
+#include <asm/proc-armv/ptrace.h>
+#include <s3c6400.h>
+
+static ulong timer_load_val;
+
+#define PRESCALER	167
+
+static s3c64xx_timers *s3c64xx_get_base_timers(void)
+{
+	return (s3c64xx_timers *)ELFIN_TIMER_BASE;
+}
+
+/* macro to read the 16 bit timer */
+static inline ulong read_timer(void)
+{
+	s3c64xx_timers *const timers = s3c64xx_get_base_timers();
+
+	return timers->TCNTO4;
+}
+
+/* Internal tick units */
+/* Last decremneter snapshot */
+static unsigned long lastdec;
+/* Monotonic incrementing timer */
+static unsigned long long timestamp;
+
+void enable_interrupts(void)
+{
+	return;
+}
+int disable_interrupts(void)
+{
+	return 0;
+}
+
+void bad_mode(void)
+{
+	panic("Resetting CPU ...\n");
+	reset_cpu(0);
+}
+
+void show_regs(struct pt_regs *regs)
+{
+	unsigned long flags;
+	const char *processor_modes[] = {
+		"USER_26", "FIQ_26", "IRQ_26", "SVC_26",
+		"UK4_26", "UK5_26", "UK6_26", "UK7_26",
+		"UK8_26", "UK9_26", "UK10_26", "UK11_26",
+		"UK12_26", "UK13_26", "UK14_26", "UK15_26",
+		"USER_32", "FIQ_32", "IRQ_32", "SVC_32",
+		"UK4_32", "UK5_32", "UK6_32", "ABT_32",
+		"UK8_32", "UK9_32", "UK10_32", "UND_32",
+		"UK12_32", "UK13_32", "UK14_32", "SYS_32",
+	};
+
+	flags = condition_codes(regs);
+
+	printf("pc : [<%08lx>]	   lr : [<%08lx>]\n"
+	       "sp : %08lx  ip : %08lx	 fp : %08lx\n",
+	       instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp, regs->ARM_ip, regs->ARM_fp);
+	printf("r10: %08lx  r9 : %08lx	 r8 : %08lx\n", regs->ARM_r10, regs->ARM_r9, regs->ARM_r8);
+	printf("r7 : %08lx  r6 : %08lx	 r5 : %08lx  r4 : %08lx\n",
+	       regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+	printf("r3 : %08lx  r2 : %08lx	 r1 : %08lx  r0 : %08lx\n",
+	       regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+	printf("Flags: %c%c%c%c",
+	       flags & CC_N_BIT ? 'N' : 'n',
+	       flags & CC_Z_BIT ? 'Z' : 'z',
+	       flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+	printf("  IRQs %s  FIQs %s  Mode %s%s\n",
+	       interrupts_enabled(regs) ? "on" : "off",
+	       fast_interrupts_enabled(regs) ? "on" : "off",
+	       processor_modes[processor_mode(regs)], thumb_mode(regs) ?
+	       " (T)" : "");
+}
+
+void do_undefined_instruction(struct pt_regs *pt_regs)
+{
+	printf("undefined instruction\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_software_interrupt(struct pt_regs *pt_regs)
+{
+	printf("software interrupt\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_prefetch_abort(struct pt_regs *pt_regs)
+{
+	printf("prefetch abort\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_data_abort(struct pt_regs *pt_regs)
+{
+	printf("data abort\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_not_used(struct pt_regs *pt_regs)
+{
+	printf("not used\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_fiq(struct pt_regs *pt_regs)
+{
+	printf("fast interrupt request\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_irq(struct pt_regs *pt_regs)
+{
+	printf("interrupt request\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+int interrupt_init(void)
+{
+	s3c64xx_timers *const timers = s3c64xx_get_base_timers();
+
+	/* use PWM Timer 4 because it has no output */
+	/*
+	 * We use the following scheme for the timer:
+	 * Prescaler is hard fixed at 167, divider at 1/4.
+	 * This gives at PCLK frequency 66MHz approx. 10us ticks
+	 * The timer is set to wrap after 100s, at 66MHz this obviously
+	 * happens after 10,000,000 ticks. A long variable can thus
+	 * keep values up to 40,000s, i.e., 11 hours. This should be
+	 * enough for most uses:-) Possible optimizations: select a
+	 * binary-friendly frequency, e.g., 1ms / 128. Also calculate
+	 * the prescaler automatically for other PCLK frequencies.
+	 */
+	/* Set timer frequency to 500KHz, at 66MHz we get prescaler=132 < 255 */
+	timers->TCFG0 = PRESCALER << 8;
+	if (timer_load_val == 0) {
+		/*
+		 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 and
+		 * prescaler = 16. Should be 10390 @33.25MHz and 15625 @ 50 MHz
+		 */
+		timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */
+		/*printf("Calculated %lu timer_load_val\n", timer_load_val);*/
+		timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000;
+	}
+
+	/* load value for 10 ms timeout */
+	lastdec = timers->TCNTB4 = timer_load_val;
+	/* auto load, manual update of Timer 4 */
+	timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO |
+		TCON_4_UPDATE;
+	/* auto load, start Timer 4 */
+	timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON;
+	timestamp = 0;
+
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	ulong now = read_timer();
+
+	if (lastdec >= now) {
+		/* normal mode */
+		timestamp += lastdec - now;
+	} else {
+		/* we have an overflow ... */
+		timestamp += lastdec + timer_load_val - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	/* We overrun in 100s */
+	return (ulong)(timer_load_val / 100);
+}
+
+void reset_timer_masked(void)
+{
+	/* reset time */
+	lastdec = read_timer();
+	timestamp = 0;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer_masked(void)
+{
+	return get_ticks() / (timer_load_val / (100 * CFG_HZ));
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t * (timer_load_val / (100 * CFG_HZ));
+}
+
+void udelay(unsigned long usec)
+{
+	unsigned long long tmp;
+	ulong tmo;
+
+	tmo = (usec + 9) / 10;
+	tmp = get_ticks() + tmo;	/* get current timestamp */
+
+	while (get_ticks() < tmp)/* loop till event */
+		 /*NOP*/;
+}
diff --git a/cpu/arm1176/s3c64xx/speed.c b/cpu/arm1176/s3c64xx/speed.c
new file mode 100644
index 0000000..bb54cb3
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/speed.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2001-2004
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * 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
+ */
+
+/*
+ * This code should work for both the S3C2400 and the S3C2410
+ * as they seem to have the same PLL and clock machinery inside.
+ * The different address mapping is handled by the s3c24xx.h files below.
+ */
+
+#include <common.h>
+#include <s3c6400.h>
+
+#define APLL 0
+#define MPLL 1
+#define EPLL 2
+
+/* ------------------------------------------------------------------------- */
+/*
+ * NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+static ulong get_PLLCLK(int pllreg)
+{
+	ulong r, m, p, s;
+
+	if (pllreg == APLL)
+		r = APLL_CON_REG;
+	else if (pllreg == MPLL)
+		r = MPLL_CON_REG;
+	else if (pllreg == EPLL)
+		r = EPLL_CON0_REG;
+	else
+		hang();
+
+	m = (r >> 16) & 0x3ff;
+	p = (r >> 8) & 0x3f;
+	s = r & 0x7;
+
+	return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s)));
+}
+
+/* return ARMCORE frequency */
+ulong get_ARMCLK(void)
+{
+	ulong div;
+
+	div = CLK_DIV0_REG;
+
+	return get_PLLCLK(APLL) / ((div & 0x7) + 1);
+}
+
+/* return FCLK frequency */
+ulong get_FCLK(void)
+{
+	return get_PLLCLK(APLL);
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+	ulong fclk;
+
+	uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
+	uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1;
+
+	/*
+	 * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on
+	 * s3c6400 and is always 0, and it is indeed running in ASYNC mode
+	 */
+	if (OTHERS_REG & 0x80)
+		fclk = get_FCLK();		/* SYNC Mode	*/
+	else
+		fclk = get_PLLCLK(MPLL);	/* ASYNC Mode	*/
+
+	return fclk / (hclk_div * hclkx2_div);
+}
+
+/* return PCLK frequency */
+ulong get_PCLK(void)
+{
+	ulong fclk;
+	uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
+	uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1;
+
+	if (OTHERS_REG & 0x80)
+		fclk = get_FCLK();		/* SYNC Mode	*/
+	else
+		fclk = get_PLLCLK(MPLL);	/* ASYNC Mode	*/
+
+	return fclk / (hclkx2_div * pre_div);
+}
+
+/* return UCLK frequency */
+ulong get_UCLK(void)
+{
+	return get_PLLCLK(EPLL);
+}
+
+int print_cpuinfo(void)
+{
+	printf("\nCPU:     S3C6400@%luMHz\n", get_ARMCLK() / 1000000);
+	printf("         Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ",
+	       get_FCLK() / 1000000, get_HCLK() / 1000000,
+	       get_PCLK() / 1000000);
+
+	if (OTHERS_REG & 0x80)
+		printf("(SYNC Mode) \n");
+	else
+		printf("(ASYNC Mode) \n");
+	return 0;
+}
diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S
new file mode 100644
index 0000000..00cc186
--- /dev/null
+++ b/cpu/arm1176/start.S
@@ -0,0 +1,469 @@
+/*
+ *  armboot - Startup Code for S3C6400/ARM1176 CPU-core
+ *
+ * Copyright (c) 2007	Samsung Electronics
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+ *
+ * 2007-09-21 - Restructured codes by jsgood (jsgood.yang at samsung.com)
+ * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
+ * jsgood (jsgood.yang at samsung.com)
+ * Base codes by scsuh (sc.suh)
+ */
+
+#include <config.h>
+#include <version.h>
+#ifdef CONFIG_ENABLE_MMU
+#include <asm/proc/domain.h>
+#endif
+#include <s3c6400.h>
+
+#if !defined(CONFIG_ENABLE_MMU) && !defined(CFG_PHY_UBOOT_BASE)
+#define CFG_PHY_UBOOT_BASE	CFG_UBOOT_BASE
+#endif
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table as in table 3.1 in [1]
+ *
+ *************************************************************************
+ */
+
+.globl _start
+_start: b	reset
+#ifndef CONFIG_NAND_SPL
+	ldr	pc, _undefined_instruction
+	ldr	pc, _software_interrupt
+	ldr	pc, _prefetch_abort
+	ldr	pc, _data_abort
+	ldr	pc, _not_used
+	ldr	pc, _irq
+	ldr	pc, _fiq
+
+_undefined_instruction:
+	.word undefined_instruction
+_software_interrupt:
+	.word software_interrupt
+_prefetch_abort:
+	.word prefetch_abort
+_data_abort:
+	.word data_abort
+_not_used:
+	.word not_used
+_irq:
+	.word irq
+_fiq:
+	.word fiq
+_pad:
+	.word 0x12345678 /* now 16*4=64 */
+#else
+	. = _start + 64
+#endif
+
+.global _end_vect
+_end_vect:
+	.balignl 16,0xdeadbeef
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+/*
+ * Below variable is very important because we use MMU in U-Boot.
+ * Without it, we cannot run code correctly before MMU is ON.
+ * by scsuh.
+ */
+_TEXT_PHY_BASE:
+	.word	CFG_PHY_UBOOT_BASE
+
+.globl _armboot_start
+_armboot_start:
+	.word _start
+
+/*
+ * These are defined in the board-specific linker script.
+ */
+.globl _bss_start
+_bss_start:
+	.word __bss_start
+
+.globl _bss_end
+_bss_end:
+	.word _end
+
+/*
+ * the actual reset code
+ */
+
+reset:
+	/*
+	 * set the cpu to SVC32 mode
+	 */
+	mrs	r0,cpsr
+	bic	r0,r0,#0x3f
+	orr	r0,r0,#0xd3
+	msr	cpsr,r0
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+	/*
+	 * we do sys-critical inits only at reboot,
+	 * not when booting from ram!
+	 */
+cpu_init_crit:
+	/*
+	 * When booting from NAND - it has definitely been a reset, so, no need
+	 * to flush caches and disable the MMU
+	 */
+#ifndef CONFIG_NAND_SPL
+	/*
+	 * flush v4 I/D caches
+	 */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
+	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
+
+	/*
+	 * disable MMU stuff and caches
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
+	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
+	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
+	/* Prepare to disable the MMU */
+	adr	r1, mmu_disable_phys
+	/* We presume we're within the first 1024 bytes */
+	and	r1, r1, #0x3fc
+	ldr	r2, _TEXT_PHY_BASE
+	ldr	r3, =0xfff00000
+	and	r2, r2, r3
+	orr	r2, r2, r1
+	b	mmu_disable
+
+	.align 5
+	/* Run in a single cache-line */
+mmu_disable:
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	mov	pc, r2
+#endif
+
+mmu_disable_phys:
+	/* Peri port setup */
+	ldr	r0, =0x70000000
+	orr	r0, r0, #0x13
+	mcr	p15,0,r0,c15,c2,4       @ 256M (0x70000000 - 0x7fffffff)
+
+	/*
+	 * Go setup Memory and board specific bits prior to relocation.
+	 */
+	bl	lowlevel_init		/* go setup pll,mux,memory */
+
+after_copy:
+#ifdef CONFIG_ENABLE_MMU
+enable_mmu:
+	/* enable domain access */
+	ldr	r5, =0x0000ffff
+	mcr	p15, 0, r5, c3, c0, 0	/* load domain access register */
+
+	/* Set the TTB register */
+	ldr	r0, _mmu_table_base
+	ldr	r1, =CFG_PHY_UBOOT_BASE
+	ldr	r2, =0xfff00000
+	bic	r0, r0, r2
+	orr	r1, r0, r1
+	mcr	p15, 0, r1, c2, c0, 0
+
+	/* Enable the MMU */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #1		/* Set CR_M to enable MMU */
+
+	/* Prepare to enable the MMU */
+	adr	r1, skip_hw_init
+	and	r1, r1, #0x3fc
+	ldr	r2, _TEXT_BASE
+	ldr	r3, =0xfff00000
+	and	r2, r2, r3
+	orr	r2, r2, r1
+	b	mmu_enable
+
+	.align 5
+	/* Run in a single cache-line */
+mmu_enable:
+
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	mov	pc, r2
+#endif
+
+skip_hw_init:
+	/* Set up the stack						    */
+stack_setup:
+#ifdef CONFIG_MEMORY_UPPER_CODE
+	ldr	sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
+#else
+	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
+	sub	r0, r0, #CFG_MALLOC_LEN	/* malloc area                      */
+	sub	r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
+	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
+
+#endif
+
+clear_bss:
+	ldr	r0, _bss_start		/* find start of bss segment        */
+	ldr	r1, _bss_end		/* stop here                        */
+	mov 	r2, #0			/* clear                            */
+
+clbss_l:
+	str	r2, [r0]		/* clear loop...                    */
+	add	r0, r0, #4
+	cmp	r0, r1
+	ble	clbss_l
+
+#ifndef CONFIG_NAND_SPL
+	ldr	pc, _start_armboot
+
+_start_armboot:
+	.word start_armboot
+#else
+	b	nand_boot
+/*	.word nand_boot*/
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+_mmu_table_base:
+	.word mmu_table
+#endif
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * we assume that cache operation is done before. (eg. cleanup_before_linux())
+ * actually, we don't need to do anything about cache if not use d-cache in
+ * U-Boot. So, in this function we clean only MMU. by scsuh
+ *
+ * void	theLastJump(void *kernel, int arch_num, uint boot_params);
+ */
+#ifdef CONFIG_ENABLE_MMU
+	.globl theLastJump
+theLastJump:
+	mov	r9, r0
+	ldr	r3, =0xfff00000
+	ldr	r4, _TEXT_PHY_BASE
+	adr	r5, phy_last_jump
+	bic	r5, r5, r3
+	orr	r5, r5, r4
+	mov	pc, r5
+phy_last_jump:
+	/*
+	 * disable MMU stuff
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	/* clear bits 13, 9:8 (--V- --RS) */
+	bic	r0, r0, #0x00000087	/* clear bits 7, 2:0 (B--- -CAM) */
+	orr	r0, r0, #0x00000002	/* set bit 2 (A) Align */
+	orr	r0, r0, #0x00001000	/* set bit 12 (I) I-Cache */
+	mcr	p15, 0, r0, c1, c0, 0
+
+	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
+
+	mov	r0, #0
+	mov	pc, r9
+#endif
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+@
+@ IRQ stack frame.
+@
+#define S_FRAME_SIZE	72
+
+#define S_OLD_R0	68
+#define S_PSR		64
+#define S_PC		60
+#define S_LR		56
+#define S_SP		52
+
+#define S_IP		48
+#define S_FP		44
+#define S_R10		40
+#define S_R9		36
+#define S_R8		32
+#define S_R7		28
+#define S_R6		24
+#define S_R5		20
+#define S_R4		16
+#define S_R3		12
+#define S_R2		8
+#define S_R1		4
+#define S_R0		0
+
+#define MODE_SVC 0x13
+#define I_BIT	 0x80
+
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ */
+
+	.macro	bad_save_user_regs
+	/* carve out a frame on current user stack */
+	sub	sp, sp, #S_FRAME_SIZE
+	/* Save user registers (now in svc mode) r0-r12 */
+	stmia	sp, {r0 - r12}
+
+	ldr	r2, _armboot_start
+	sub	r2, r2, #(CFG_MALLOC_LEN)
+	/* set base 2 words into abort stack */
+	sub	r2, r2, #(CFG_GBL_DATA_SIZE+8)
+	/* get values for "aborted" pc and cpsr (into parm regs) */
+	ldmia	r2, {r2 - r3}
+	/* grab pointer to old stack */
+	add	r0, sp, #S_FRAME_SIZE
+
+	add	r5, sp, #S_SP
+	mov	r1, lr
+	/* save sp_SVC, lr_SVC, pc, cpsr */
+	stmia	r5, {r0 - r3}
+	/* save current stack into r0 (param register) */
+	mov	r0, sp
+	.endm
+
+	.macro get_bad_stack
+	/* setup our mode stack (enter in banked mode) */
+	ldr	r13, _armboot_start
+	/* move past malloc pool */
+	sub	r13, r13, #(CFG_MALLOC_LEN)
+	/* move to reserved a couple spots for abort stack */
+	sub	r13, r13, #(CFG_GBL_DATA_SIZE + 8)
+
+	/* save caller lr in position 0 of saved stack */
+	str	lr, [r13]
+	/* get the spsr */
+	mrs	lr, spsr
+	/* save spsr in position 1 of saved stack */
+	str	lr, [r13, #4]
+
+	/* prepare SVC-Mode */
+	mov	r13, #MODE_SVC
+	@ msr	spsr_c, r13
+	/* switch modes, make sure moves will execute */
+	msr	spsr, r13
+	/* capture return pc */
+	mov	lr, pc
+	/* jump to next instruction & switch modes. */
+	movs	pc, lr
+	.endm
+
+	.macro get_bad_stack_swi
+	/* space on current stack for scratch reg. */
+	sub	r13, r13, #4
+	/* save R0's value. */
+	str	r0, [r13]
+	/* get data regions start */
+	ldr	r0, _armboot_start
+	/* move past malloc pool */
+	sub	r0, r0, #(CFG_MALLOC_LEN)
+	/* move past gbl and a couple spots for abort stack */
+	sub	r0, r0, #(CFG_GBL_DATA_SIZE + 8)
+	/* save caller lr in position 0 of saved stack */
+	str	lr, [r0]
+	/* get the spsr */
+	mrs	r0, spsr
+	/* save spsr in position 1 of saved stack */
+	str	lr, [r0, #4]
+	/* restore r0 */
+	ldr	r0, [r13]
+	/* pop stack entry */
+	add	r13, r13, #4
+	.endm
+
+/*
+ * exception handlers
+ */
+	.align	5
+undefined_instruction:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_undefined_instruction
+
+	.align	5
+software_interrupt:
+	get_bad_stack_swi
+	bad_save_user_regs
+	bl	do_software_interrupt
+
+	.align	5
+prefetch_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_prefetch_abort
+
+	.align	5
+data_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_data_abort
+
+	.align	5
+not_used:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_not_used
+
+	.align	5
+irq:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_irq
+
+	.align	5
+fiq:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_fiq
+#endif /* CONFIG_NAND_SPL */
diff --git a/include/asm-arm/arch-s3c64xx/hardware.h b/include/asm-arm/arch-s3c64xx/hardware.h
new file mode 100644
index 0000000..84d24c9
--- /dev/null
+++ b/include/asm-arm/arch-s3c64xx/hardware.h
@@ -0,0 +1,63 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 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 _ARCH_HARDWARE_H_
+#define _ARCH_HARDWARE_H_
+
+#include <asm/sizes.h>
+
+#ifndef __ASSEMBLY__
+#define UData(Data)	((unsigned long) (Data))
+
+#define __REG(x)	(*(vu_long *)(x))
+#define __REGl(x)	(*(vu_long *)(x))
+#define __REGw(x)	(*(vu_short *)(x))
+#define __REGb(x)	(*(vu_char *)(x))
+#define __REG2(x, y)	(*(vu_long *)((x) + (y)))
+#else
+#define UData(Data)	(Data)
+
+#define __REG(x)	(x)
+#define __REGl(x)	(x)
+#define __REGw(x)	(x)
+#define __REGb(x)	(x)
+#define __REG2(x, y)	((x) + (y))
+#endif
+
+#define Fld(Size, Shft)	(((Size) << 16) + (Shft))
+
+#define FSize(Field)	((Field) >> 16)
+#define FShft(Field)	((Field) & 0x0000FFFF)
+#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field)	(UData (1) << FShft (Field))
+
+#define FClrBit(Data, Bit)	(Data = (Data & ~(Bit)))
+#define FClrFld(Data, Field)	(Data = (Data & ~FMsk(Field)))
+
+#define FInsrt(Value, Field) \
+			(UData (Value) << FShft (Field))
+
+#define FExtr(Data, Field) \
+			((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+#endif /* _ARCH_HARDWARE_H_ */
diff --git a/include/common.h b/include/common.h
index 2fcb1fd..10d56e0 100644
--- a/include/common.h
+++ b/include/common.h
@@ -489,7 +489,8 @@ int	prt_mpc8220_clks (void);
 ulong	get_OPB_freq (void);
 ulong	get_PCI_freq (void);
 #endif
-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X)
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
+	defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400)
 void	s3c2410_irq(void);
 #define ARM920_IRQ_CALLBACK s3c2410_irq
 ulong	get_FCLK (void);
diff --git a/include/s3c6400.h b/include/s3c6400.h
new file mode 100644
index 0000000..742aeee
--- /dev/null
+++ b/include/s3c6400.h
@@ -0,0 +1,866 @@
+/*
+ * (C) Copyright 2007
+ * Byungjae Lee, Samsung Erectronics, bjlee at samsung.com.
+ *      - only support for S3C6400
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 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	    : s3c6400.h
+ *
+ * Based on S3C6400 User's manual Rev 0.0
+ ************************************************/
+
+#ifndef __S3C6400_H__
+#define __S3C6400_H__
+
+#ifndef CONFIG_S3C6400
+#define CONFIG_S3C6400		1
+#endif
+
+#define S3C64XX_UART_CHANNELS	3
+#define S3C64XX_SPI_CHANNELS	2
+
+#include <asm/hardware.h>
+
+#define ELFIN_CLOCK_POWER_BASE	0x7e00f000
+
+/* Clock & Power Controller for mDirac3*/
+#define APLL_LOCK_OFFSET	0x00
+#define MPLL_LOCK_OFFSET	0x04
+#define EPLL_LOCK_OFFSET	0x08
+#define APLL_CON_OFFSET		0x0C
+#define MPLL_CON_OFFSET		0x10
+#define EPLL_CON0_OFFSET	0x14
+#define EPLL_CON1_OFFSET	0x18
+#define CLK_SRC_OFFSET		0x1C
+#define CLK_DIV0_OFFSET		0x20
+#define CLK_DIV1_OFFSET		0x24
+#define CLK_DIV2_OFFSET		0x28
+#define CLK_OUT_OFFSET		0x2C
+#define HCLK_GATE_OFFSET	0x30
+#define PCLK_GATE_OFFSET	0x34
+#define SCLK_GATE_OFFSET	0x38
+#define AHB_CON0_OFFSET		0x100
+#define AHB_CON1_OFFSET		0x104
+#define AHB_CON2_OFFSET		0x108
+#define SELECT_DMA_OFFSET	0x110
+#define SW_RST_OFFSET		0x114
+#define SYS_ID_OFFSET		0x118
+#define MEM_SYS_CFG_OFFSET	0x120
+#define QOS_OVERRIDE0_OFFSET	0x124
+#define QOS_OVERRIDE1_OFFSET	0x128
+#define MEM_CFG_STAT_OFFSET	0x12C
+#define PWR_CFG_OFFSET		0x804
+#define EINT_MASK_OFFSET	0x808
+#define NOR_CFG_OFFSET		0x810
+#define STOP_CFG_OFFSET		0x814
+#define SLEEP_CFG_OFFSET	0x818
+#define OSC_FREQ_OFFSET		0x820
+#define OSC_STABLE_OFFSET	0x824
+#define PWR_STABLE_OFFSET	0x828
+#define FPC_STABLE_OFFSET	0x82C
+#define MTC_STABLE_OFFSET	0x830
+#define OTHERS_OFFSET		0x900
+#define RST_STAT_OFFSET		0x904
+#define WAKEUP_STAT_OFFSET	0x908
+#define BLK_PWR_STAT_OFFSET	0x90C
+#define INF_REG0_OFFSET		0xA00
+#define INF_REG1_OFFSET		0xA04
+#define INF_REG2_OFFSET		0xA08
+#define INF_REG3_OFFSET		0xA0C
+#define INF_REG4_OFFSET		0xA10
+#define INF_REG5_OFFSET		0xA14
+#define INF_REG6_OFFSET		0xA18
+#define INF_REG7_OFFSET		0xA1C
+
+#define OSC_CNT_VAL_OFFSET	0x824
+#define PWR_CNT_VAL_OFFSET	0x828
+#define FPC_CNT_VAL_OFFSET	0x82C
+#define MTC_CNT_VAL_OFFSET	0x830
+
+#define APLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET)
+#define MPLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET)
+#define EPLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET)
+#define APLL_CON_REG		__REG(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET)
+#define MPLL_CON_REG		__REG(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET)
+#define EPLL_CON0_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET)
+#define EPLL_CON1_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET)
+#define CLK_SRC_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET)
+#define CLK_DIV0_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET)
+#define CLK_DIV1_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET)
+#define CLK_DIV2_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET)
+#define CLK_OUT_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET)
+#define HCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET)
+#define PCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET)
+#define SCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET)
+#define AHB_CON0_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET)
+#define AHB_CON1_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET)
+#define AHB_CON2_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET)
+#define SELECT_DMA_REG		__REG(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET)
+#define SW_RST_REG		__REG(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET)
+#define SYS_ID_REG		__REG(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET)
+#define MEM_SYS_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET)
+#define QOS_OVERRIDE0_REG	__REG(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET)
+#define QOS_OVERRIDE1_REG	__REG(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET)
+#define MEM_CFG_STAT_REG	__REG(ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET)
+#define PWR_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET)
+#define EINT_MASK_REG		__REG(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET)
+#define NOR_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET)
+#define STOP_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET)
+#define SLEEP_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET)
+#define OSC_FREQ_REG		__REG(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET)
+#define OSC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET)
+#define PWR_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET)
+#define FPC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET)
+#define MTC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET)
+#define OTHERS_REG		__REG(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET)
+#define RST_STAT_REG		__REG(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
+#define WAKEUP_STAT_REG		__REG(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)
+#define BLK_PWR_STAT_REG	__REG(ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET)
+#define INF_REG0_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)
+#define INF_REG1_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET)
+#define INF_REG2_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET)
+#define INF_REG3_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET)
+#define INF_REG4_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET)
+#define INF_REG5_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET)
+#define INF_REG6_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET)
+#define INF_REG7_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET)
+
+#define APLL_LOCK	(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET)
+#define MPLL_LOCK	(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET)
+#define EPLL_LOCK	(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET)
+#define APLL_CON	(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET)
+#define MPLL_CON	(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET)
+#define EPLL_CON0	(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET)
+#define EPLL_CON1	(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET)
+#define CLK_SRC		(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET)
+#define CLK_DIV0	(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET)
+#define CLK_DIV1	(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET)
+#define CLK_DIV2	(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET)
+#define CLK_OUT		(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET)
+#define HCLK_GATE	(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET)
+#define PCLK_GATE	(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET)
+#define SCLK_GATE	(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET)
+#define AHB_CON0	(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET)
+#define AHB_CON1	(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET)
+#define AHB_CON2	(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET)
+#define SELECT_DMA	(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET)
+#define SW_RST		(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET)
+#define SYS_ID		(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET)
+#define MEM_SYS_CFG	(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET)
+#define QOS_OVERRIDE0	(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET)
+#define QOS_OVERRIDE1	(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET)
+#define MEM_CFG_STAT	(ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET)
+#define PWR_CFG		(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET)
+#define EINT_MASK	(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET)
+#define NOR_CFG		(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET)
+#define STOP_CFG	(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET)
+#define SLEEP_CFG	(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET)
+#define OSC_FREQ	(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET)
+#define OSC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET)
+#define PWR_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET)
+#define FPC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET)
+#define MTC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET)
+#define OTHERS		(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET)
+#define RST_STAT	(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
+#define WAKEUP_STAT	(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)
+#define BLK_PWR_STAT	(ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET)
+#define INF_REG0	(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)
+#define INF_REG1	(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET)
+#define INF_REG2	(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET)
+#define INF_REG3	(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET)
+#define INF_REG4	(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET)
+#define INF_REG5	(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET)
+#define INF_REG6	(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET)
+#define INF_REG7	(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET)
+
+
+/*
+ * GPIO
+ */
+#define ELFIN_GPIO_BASE		0x7f008000
+
+#define GPACON_OFFSET		0x00
+#define GPADAT_OFFSET		0x04
+#define GPAPUD_OFFSET		0x08
+#define GPACONSLP_OFFSET	0x0C
+#define GPAPUDSLP_OFFSET	0x10
+#define GPBCON_OFFSET		0x20
+#define GPBDAT_OFFSET		0x04
+#define GPBPUD_OFFSET		0x08
+#define GPBCONSLP_OFFSET	0x0C
+#define GPBPUDSLP_OFFSET	0x30
+#define GPCCON_OFFSET		0x40
+#define GPCDAT_OFFSET		0x44
+#define GPCPUD_OFFSET		0x48
+#define GPCCONSLP_OFFSET	0x4C
+#define GPCPUDSLP_OFFSET	0x50
+#define GPDCON_OFFSET		0x60
+#define GPDDAT_OFFSET		0x64
+#define GPDPUD_OFFSET		0x68
+#define GPDCONSLP_OFFSET	0x6C
+#define GPDPUDSLP_OFFSET	0x70
+#define GPECON_OFFSET		0x80
+#define GPEDAT_OFFSET		0x84
+#define GPEPUD_OFFSET		0x88
+#define GPECONSLP_OFFSET	0x8C
+#define GPEPUDSLP_OFFSET	0x90
+#define GPFCON_OFFSET		0xA0
+#define GPFDAT_OFFSET		0xA4
+#define GPFPUD_OFFSET		0xA8
+#define GPFCONSLP_OFFSET	0xAC
+#define GPFPUDSLP_OFFSET	0xB0
+#define GPGCON_OFFSET		0xC0
+#define GPGDAT_OFFSET		0xC4
+#define GPGPUD_OFFSET		0xC8
+#define GPGCONSLP_OFFSET	0xCC
+#define GPGPUDSLP_OFFSET	0xD0
+#define GPHCON0_OFFSET		0xE0
+#define GPHCON1_OFFSET		0xE4
+#define GPHDAT_OFFSET		0xE8
+#define GPHPUD_OFFSET		0xEC
+#define GPHCONSLP_OFFSET	0xF0
+#define GPHPUDSLP_OFFSET	0xF4
+#define GPICON_OFFSET		0x100
+#define GPIDAT_OFFSET		0x104
+#define GPIPUD_OFFSET		0x108
+#define GPICONSLP_OFFSET	0x10C
+#define GPIPUDSLP_OFFSET	0x110
+#define GPJCON_OFFSET		0x120
+#define GPJDAT_OFFSET		0x124
+#define GPJPUD_OFFSET		0x128
+#define GPJCONSLP_OFFSET	0x12C
+#define GPJPUDSLP_OFFSET	0x130
+#define MEM0DRVCON_OFFSET	0x1D0
+#define MEM1DRVCON_OFFSET	0x1D4
+#define GPKCON0_OFFSET		0x800
+#define GPKCON1_OFFSET		0x804
+#define GPKDAT_OFFSET		0x808
+#define GPKPUD_OFFSET		0x80C
+#define GPLCON0_OFFSET		0x810
+#define GPLCON1_OFFSET		0x814
+#define GPLDAT_OFFSET		0x818
+#define GPLPUD_OFFSET		0x81C
+#define GPMCON_OFFSET		0x820
+#define GPMDAT_OFFSET		0x824
+#define GPMPUD_OFFSET		0x828
+#define GPNCON_OFFSET		0x830
+#define GPNDAT_OFFSET		0x834
+#define GPNPUD_OFFSET		0x838
+#define GPOCON_OFFSET		0x140
+#define GPODAT_OFFSET		0x144
+#define GPOPUD_OFFSET		0x148
+#define GPOCONSLP_OFFSET	0x14C
+#define GPOPUDSLP_OFFSET	0x150
+#define GPPCON_OFFSET		0x160
+#define GPPDAT_OFFSET		0x164
+#define GPPPUD_OFFSET		0x168
+#define GPPCONSLP_OFFSET	0x16C
+#define GPPPUDSLP_OFFSET	0x170
+#define GPQCON_OFFSET		0x180
+#define GPQDAT_OFFSET		0x184
+#define GPQPUD_OFFSET		0x188
+#define GPQCONSLP_OFFSET	0x18C
+#define GPQPUDSLP_OFFSET	0x190
+
+#define EINTPEND_OFFSET		0x924
+
+#define GPACON_REG		__REG(ELFIN_GPIO_BASE+GPACON_OFFSET)
+#define GPADAT_REG		__REG(ELFIN_GPIO_BASE+GPADAT_OFFSET)
+#define GPAPUD_REG		__REG(ELFIN_GPIO_BASE+GPAPUD_OFFSET)
+#define GPACONSLP_REG		__REG(ELFIN_GPIO_BASE+GPACONSLP_OFFSET)
+#define GPAPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET)
+#define GPBCON_REG		__REG(ELFIN_GPIO_BASE+GPBCON_OFFSET)
+#define GPBDAT_REG		__REG(ELFIN_GPIO_BASE+GPBDAT_OFFSET)
+#define GPBPUD_REG		__REG(ELFIN_GPIO_BASE+GPBPUD_OFFSET)
+#define GPBCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET)
+#define GPBPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET)
+#define GPCCON_REG		__REG(ELFIN_GPIO_BASE+GPCCON_OFFSET)
+#define GPCDAT_REG		__REG(ELFIN_GPIO_BASE+GPCDAT_OFFSET)
+#define GPCPUD_REG		__REG(ELFIN_GPIO_BASE+GPCPUD_OFFSET)
+#define GPCCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET)
+#define GPCPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET)
+#define GPDCON_REG		__REG(ELFIN_GPIO_BASE+GPDCON_OFFSET)
+#define GPDDAT_REG		__REG(ELFIN_GPIO_BASE+GPDDAT_OFFSET)
+#define GPDPUD_REG		__REG(ELFIN_GPIO_BASE+GPDPUD_OFFSET)
+#define GPDCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET)
+#define GPDPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET)
+#define GPECON_REG		__REG(ELFIN_GPIO_BASE+GPECON_OFFSET)
+#define GPEDAT_REG		__REG(ELFIN_GPIO_BASE+GPEDAT_OFFSET)
+#define GPEPUD_REG		__REG(ELFIN_GPIO_BASE+GPEPUD_OFFSET)
+#define GPECONSLP_REG		__REG(ELFIN_GPIO_BASE+GPECONSLP_OFFSET)
+#define GPEPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET)
+#define GPFCON_REG		__REG(ELFIN_GPIO_BASE+GPFCON_OFFSET)
+#define GPFDAT_REG		__REG(ELFIN_GPIO_BASE+GPFDAT_OFFSET)
+#define GPFPUD_REG		__REG(ELFIN_GPIO_BASE+GPFPUD_OFFSET)
+#define GPFCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET)
+#define GPFPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET)
+#define GPGCON_REG		__REG(ELFIN_GPIO_BASE+GPGCON_OFFSET)
+#define GPGDAT_REG		__REG(ELFIN_GPIO_BASE+GPGDAT_OFFSET)
+#define GPGPUD_REG		__REG(ELFIN_GPIO_BASE+GPGPUD_OFFSET)
+#define GPGCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET)
+#define GPGPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET)
+#define GPHCON0_REG		__REG(ELFIN_GPIO_BASE+GPHCON0_OFFSET)
+#define GPHCON1_REG		__REG(ELFIN_GPIO_BASE+GPHCON1_OFFSET)
+#define GPHDAT_REG		__REG(ELFIN_GPIO_BASE+GPHDAT_OFFSET)
+#define GPHPUD_REG		__REG(ELFIN_GPIO_BASE+GPHPUD_OFFSET)
+#define GPHCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET)
+#define GPHPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET)
+#define GPICON_REG		__REG(ELFIN_GPIO_BASE+GPICON_OFFSET)
+#define GPIDAT_REG		__REG(ELFIN_GPIO_BASE+GPIDAT_OFFSET)
+#define GPIPUD_REG		__REG(ELFIN_GPIO_BASE+GPIPUD_OFFSET)
+#define GPICONSLP_REG		__REG(ELFIN_GPIO_BASE+GPICONSLP_OFFSET)
+#define GPIPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET)
+#define GPJCON_REG		__REG(ELFIN_GPIO_BASE+GPJCON_OFFSET)
+#define GPJDAT_REG		__REG(ELFIN_GPIO_BASE+GPJDAT_OFFSET)
+#define GPJPUD_REG		__REG(ELFIN_GPIO_BASE+GPJPUD_OFFSET)
+#define GPJCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET)
+#define GPJPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET)
+#define GPKCON0_REG		__REG(ELFIN_GPIO_BASE+GPKCON0_OFFSET)
+#define GPKCON1_REG		__REG(ELFIN_GPIO_BASE+GPKCON1_OFFSET)
+#define GPKDAT_REG		__REG(ELFIN_GPIO_BASE+GPKDAT_OFFSET)
+#define GPKPUD_REG		__REG(ELFIN_GPIO_BASE+GPKPUD_OFFSET)
+#define GPLCON0_REG		__REG(ELFIN_GPIO_BASE+GPLCON0_OFFSET)
+#define GPLCON1_REG		__REG(ELFIN_GPIO_BASE+GPLCON1_OFFSET)
+#define GPLDAT_REG		__REG(ELFIN_GPIO_BASE+GPLDAT_OFFSET)
+#define GPLPUD_REG		__REG(ELFIN_GPIO_BASE+GPLPUD_OFFSET)
+#define GPMCON_REG		__REG(ELFIN_GPIO_BASE+GPMCON_OFFSET)
+#define GPMDAT_REG		__REG(ELFIN_GPIO_BASE+GPMDAT_OFFSET)
+#define GPMPUD_REG		__REG(ELFIN_GPIO_BASE+GPMPUD_OFFSET)
+#define GPNCON_REG		__REG(ELFIN_GPIO_BASE+GPNCON_OFFSET)
+#define GPNDAT_REG		__REG(ELFIN_GPIO_BASE+GPNDAT_OFFSET)
+#define GPNPUD_REG		__REG(ELFIN_GPIO_BASE+GPNPUD_OFFSET)
+#define GPOCON_REG		__REG(ELFIN_GPIO_BASE+GPOCON_OFFSET)
+#define GPODAT_REG		__REG(ELFIN_GPIO_BASE+GPODAT_OFFSET)
+#define GPOPUD_REG		__REG(ELFIN_GPIO_BASE+GPOPUD_OFFSET)
+#define GPOCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET)
+#define GPOPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET)
+#define GPPCON_REG		__REG(ELFIN_GPIO_BASE+GPPCON_OFFSET)
+#define GPPDAT_REG		__REG(ELFIN_GPIO_BASE+GPPDAT_OFFSET)
+#define GPPPUD_REG		__REG(ELFIN_GPIO_BASE+GPPPUD_OFFSET)
+#define GPPCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET)
+#define GPPPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET)
+#define GPQCON_REG		__REG(ELFIN_GPIO_BASE+GPQCON_OFFSET)
+#define GPQDAT_REG		__REG(ELFIN_GPIO_BASE+GPQDAT_OFFSET)
+#define GPQPUD_REG		__REG(ELFIN_GPIO_BASE+GPQPUD_OFFSET)
+#define GPQCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET)
+#define GPQPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET)
+
+/*
+ * Bus Matrix
+ */
+#define ELFIN_MEM_SYS_CFG      0x7e00f120
+
+#define GPACON		(ELFIN_GPIO_BASE+GPACON_OFFSET)
+#define GPADAT		(ELFIN_GPIO_BASE+GPADAT_OFFSET)
+#define GPAPUD		(ELFIN_GPIO_BASE+GPAPUD_OFFSET)
+#define GPACONSLP	(ELFIN_GPIO_BASE+GPACONSLP_OFFSET)
+#define GPAPUDSLP	(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET)
+#define GPBCON		(ELFIN_GPIO_BASE+GPBCON_OFFSET)
+#define GPBDAT		(ELFIN_GPIO_BASE+GPBDAT_OFFSET)
+#define GPBPUD		(ELFIN_GPIO_BASE+GPBPUD_OFFSET)
+#define GPBCONSLP	(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET)
+#define GPBPUDSLP	(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET)
+#define GPCCON		(ELFIN_GPIO_BASE+GPCCON_OFFSET)
+#define GPCDAT		(ELFIN_GPIO_BASE+GPCDAT_OFFSET)
+#define GPCPUD		(ELFIN_GPIO_BASE+GPCPUD_OFFSET)
+#define GPCCONSLP	(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET)
+#define GPCPUDSLP	(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET)
+#define GPDCON		(ELFIN_GPIO_BASE+GPDCON_OFFSET)
+#define GPDDAT		(ELFIN_GPIO_BASE+GPDDAT_OFFSET)
+#define GPDPUD		(ELFIN_GPIO_BASE+GPDPUD_OFFSET)
+#define GPDCONSLP	(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET)
+#define GPDPUDSLP	(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET)
+#define GPECON		(ELFIN_GPIO_BASE+GPECON_OFFSET)
+#define GPEDAT		(ELFIN_GPIO_BASE+GPEDAT_OFFSET)
+#define GPEPUD		(ELFIN_GPIO_BASE+GPEPUD_OFFSET)
+#define GPECONSLP	(ELFIN_GPIO_BASE+GPECONSLP_OFFSET)
+#define GPEPUDSLP	(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET)
+#define GPFCON		(ELFIN_GPIO_BASE+GPFCON_OFFSET)
+#define GPFDAT		(ELFIN_GPIO_BASE+GPFDAT_OFFSET)
+#define GPFPUD		(ELFIN_GPIO_BASE+GPFPUD_OFFSET)
+#define GPFCONSLP	(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET)
+#define GPFPUDSLP	(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET)
+#define GPGCON		(ELFIN_GPIO_BASE+GPGCON_OFFSET)
+#define GPGDAT		(ELFIN_GPIO_BASE+GPGDAT_OFFSET)
+#define GPGPUD		(ELFIN_GPIO_BASE+GPGPUD_OFFSET)
+#define GPGCONSLP	(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET)
+#define GPGPUDSLP	(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET)
+#define GPHCON0		(ELFIN_GPIO_BASE+GPHCON0_OFFSET)
+#define GPHCON1		(ELFIN_GPIO_BASE+GPHCON1_OFFSET)
+#define GPHDAT		(ELFIN_GPIO_BASE+GPHDAT_OFFSET)
+#define GPHPUD		(ELFIN_GPIO_BASE+GPHPUD_OFFSET)
+#define GPHCONSLP	(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET)
+#define GPHPUDSLP	(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET)
+#define GPICON		(ELFIN_GPIO_BASE+GPICON_OFFSET)
+#define GPIDAT		(ELFIN_GPIO_BASE+GPIDAT_OFFSET)
+#define GPIPUD		(ELFIN_GPIO_BASE+GPIPUD_OFFSET)
+#define GPICONSLP	(ELFIN_GPIO_BASE+GPICONSLP_OFFSET)
+#define GPIPUDSLP	(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET)
+#define GPJCON		(ELFIN_GPIO_BASE+GPJCON_OFFSET)
+#define GPJDAT		(ELFIN_GPIO_BASE+GPJDAT_OFFSET)
+#define GPJPUD		(ELFIN_GPIO_BASE+GPJPUD_OFFSET)
+#define GPJCONSLP	(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET)
+#define GPJPUDSLP	(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET)
+#define GPKCON0		(ELFIN_GPIO_BASE+GPKCON0_OFFSET)
+#define GPKCON1		(ELFIN_GPIO_BASE+GPKCON1_OFFSET)
+#define GPKDAT		(ELFIN_GPIO_BASE+GPKDAT_OFFSET)
+#define GPKPUD		(ELFIN_GPIO_BASE+GPKPUD_OFFSET)
+#define GPLCON0		(ELFIN_GPIO_BASE+GPLCON0_OFFSET)
+#define GPLCON1		(ELFIN_GPIO_BASE+GPLCON1_OFFSET)
+#define GPLDAT		(ELFIN_GPIO_BASE+GPLDAT_OFFSET)
+#define GPLPUD		(ELFIN_GPIO_BASE+GPLPUD_OFFSET)
+#define GPMCON		(ELFIN_GPIO_BASE+GPMCON_OFFSET)
+#define GPMDAT		(ELFIN_GPIO_BASE+GPMDAT_OFFSET)
+#define GPMPUD		(ELFIN_GPIO_BASE+GPMPUD_OFFSET)
+#define GPNCON		(ELFIN_GPIO_BASE+GPNCON_OFFSET)
+#define GPNDAT		(ELFIN_GPIO_BASE+GPNDAT_OFFSET)
+#define GPNPUD		(ELFIN_GPIO_BASE+GPNPUD_OFFSET)
+#define GPOCON		(ELFIN_GPIO_BASE+GPOCON_OFFSET)
+#define GPODAT		(ELFIN_GPIO_BASE+GPODAT_OFFSET)
+#define GPOPUD		(ELFIN_GPIO_BASE+GPOPUD_OFFSET)
+#define GPOCONSLP	(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET)
+#define GPOPUDSLP	(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET)
+#define GPPCON		(ELFIN_GPIO_BASE+GPPCON_OFFSET)
+#define GPPDAT		(ELFIN_GPIO_BASE+GPPDAT_OFFSET)
+#define GPPPUD		(ELFIN_GPIO_BASE+GPPPUD_OFFSET)
+#define GPPCONSLP	(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET)
+#define GPPPUDSLP	(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET)
+#define GPQCON		(ELFIN_GPIO_BASE+GPQCON_OFFSET)
+#define GPQDAT		(ELFIN_GPIO_BASE+GPQDAT_OFFSET)
+#define GPQPUD		(ELFIN_GPIO_BASE+GPQPUD_OFFSET)
+#define GPQCONSLP	(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET)
+#define GPQPUDSLP	(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET)
+
+/*
+ * Memory controller
+ */
+#define ELFIN_SROM_BASE                0x70000000
+
+#define SROM_BW_REG            __REG(ELFIN_SROM_BASE+0x0)
+#define SROM_BC0_REG           __REG(ELFIN_SROM_BASE+0x4)
+#define SROM_BC1_REG           __REG(ELFIN_SROM_BASE+0x8)
+#define SROM_BC2_REG           __REG(ELFIN_SROM_BASE+0xC)
+#define SROM_BC3_REG           __REG(ELFIN_SROM_BASE+0x10)
+#define SROM_BC4_REG           __REG(ELFIN_SROM_BASE+0x14)
+#define SROM_BC5_REG           __REG(ELFIN_SROM_BASE+0x18)
+
+/*
+ * SDRAM Controller
+ */
+#define ELFIN_DMC0_BASE		0x7e000000
+#define ELFIN_DMC1_BASE		0x7e001000
+
+#define INDEX_DMC_MEMC_STATUS   (0x00)
+#define INDEX_DMC_MEMC_CMD      (0x04)
+#define INDEX_DMC_DIRECT_CMD    (0x08)
+#define INDEX_DMC_MEMORY_CFG    (0x0C)
+#define INDEX_DMC_REFRESH_PRD   (0x10)
+#define INDEX_DMC_CAS_LATENCY   (0x14)
+#define INDEX_DMC_T_DQSS        (0x18)
+#define INDEX_DMC_T_MRD         (0x1C)
+#define INDEX_DMC_T_RAS         (0x20)
+#define INDEX_DMC_T_RC          (0x24)
+#define INDEX_DMC_T_RCD         (0x28)
+#define INDEX_DMC_T_RFC         (0x2C)
+#define INDEX_DMC_T_RP          (0x30)
+#define INDEX_DMC_T_RRD         (0x34)
+#define INDEX_DMC_T_WR          (0x38)
+#define INDEX_DMC_T_WTR         (0x3C)
+#define INDEX_DMC_T_XP          (0x40)
+#define INDEX_DMC_T_XSR         (0x44)
+#define INDEX_DMC_T_ESR         (0x48)
+#define INDEX_DMC_MEMORY_CFG2	(0x4C)
+#define INDEX_DMC_CHIP_0_CFG    (0x200)
+#define INDEX_DMC_CHIP_1_CFG    (0x204)
+#define INDEX_DMC_CHIP_2_CFG    (0x208)
+#define INDEX_DMC_CHIP_3_CFG    (0x20C)
+#define INDEX_DMC_USER_STATUS	(0x300)
+#define INDEX_DMC_USER_CONFIG	(0x304)
+
+/*
+ * Memory Chip direct command
+ */
+#define DMC_NOP0	0x0c0000
+#define DMC_NOP1	0x1c0000
+#define DMC_PA0		0x000000        /* Precharge all */
+#define DMC_PA1		0x100000
+#define DMC_AR0		0x040000        /* Autorefresh */
+#define DMC_AR1		0x140000
+#define DMC_SDR_MR0	0x080032        /* MRS, CAS 3,  Burst Length 4 */
+#define DMC_SDR_MR1	0x180032
+#define DMC_DDR_MR0	0x080162
+#define DMC_DDR_MR1	0x180162
+#define DMC_mDDR_MR0	0x080032        /* CAS 3, Burst Length 4 */
+#define DMC_mDDR_MR1	0x180032
+#define DMC_mSDR_EMR0	0x0a0000        /* EMRS, DS:Full, PASR:Full Array */
+#define DMC_mSDR_EMR1	0x1a0000
+#define DMC_DDR_EMR0	0x090000
+#define DMC_DDR_EMR1	0x190000
+#define DMC_mDDR_EMR0	0x0a0000        /*  DS:Full, PASR:Full Array */
+#define DMC_mDDR_EMR1	0x1a0000
+
+/****************************************************************
+ Definitions for memory configuration
+ Set memory configuration
+	active_chips	 = 1'b0 (1 chip)
+	qos_master_chip  = 3'b000(ARID[3:0])
+	memory burst	 = 3'b010(burst 4)
+	stop_mem_clock	 = 1'b0(disable dynamical stop)
+	auto_power_down  = 1'b0(disable auto power-down mode)
+	power_down_prd	 = 6'b00_0000(0 cycle for auto power-down)
+	ap_bit		 = 1'b0 (bit position of auto-precharge is 10)
+	row_bits	 = 3'b010(# row address 13)
+	column_bits	 = 3'b010(# column address 10 )
+
+ Set user configuration
+	2'b10=SDRAM/mSDRAM, 2'b11=DDR, 2'b01=mDDR
+
+ Set chip select for chip [n]
+	 row bank control, bank address 0x3000_0000 ~ 0x37ff_ffff
+	 CHIP_[n]_CFG=0x30F8,  30: ADDR[31:24], F8: Mask[31:24]
+******************************************************************/
+
+/*
+ * Nand flash controller
+ */
+#define ELFIN_NAND_BASE		0x70200000
+
+#define NFCONF_OFFSET           0x00
+#define NFCONT_OFFSET           0x04
+#define NFCMMD_OFFSET           0x08
+#define NFADDR_OFFSET           0x0c
+#define NFDATA_OFFSET		0x10
+#define NFMECCDATA0_OFFSET      0x14
+#define NFMECCDATA1_OFFSET      0x18
+#define NFSECCDATA0_OFFSET      0x1c
+#define NFSBLK_OFFSET           0x20
+#define NFEBLK_OFFSET           0x24
+#define NFSTAT_OFFSET           0x28
+#define NFESTAT0_OFFSET         0x2c
+#define NFESTAT1_OFFSET         0x30
+#define NFMECC0_OFFSET          0x34
+#define NFMECC1_OFFSET          0x38
+#define NFSECC_OFFSET           0x3c
+#define NFMLCBITPT_OFFSET       0x40
+
+#define NFCONF			(ELFIN_NAND_BASE+NFCONF_OFFSET)
+#define NFCONT			(ELFIN_NAND_BASE+NFCONT_OFFSET)
+#define NFCMMD			(ELFIN_NAND_BASE+NFCMMD_OFFSET)
+#define NFADDR           	(ELFIN_NAND_BASE+NFADDR_OFFSET)
+#define NFDATA          	(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFMECCDATA0     	(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
+#define NFMECCDATA1     	(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
+#define NFSECCDATA0      	(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
+#define NFSBLK          	(ELFIN_NAND_BASE+NFSBLK_OFFSET)
+#define NFEBLK           	(ELFIN_NAND_BASE+NFEBLK_OFFSET)
+#define NFSTAT           	(ELFIN_NAND_BASE+NFSTAT_OFFSET)
+#define NFESTAT0         	(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
+#define NFESTAT1         	(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
+#define NFMECC0          	(ELFIN_NAND_BASE+NFMECC0_OFFSET)
+#define NFMECC1          	(ELFIN_NAND_BASE+NFMECC1_OFFSET)
+#define NFSECC           	(ELFIN_NAND_BASE+NFSECC_OFFSET)
+#define NFMLCBITPT           	(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
+
+#define NFCONF_REG		__REG(ELFIN_NAND_BASE+NFCONF_OFFSET)
+#define NFCONT_REG		__REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
+#define NFCMD_REG		__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
+#define NFADDR_REG           	__REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
+#define NFDATA_REG          	__REG(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFDATA8_REG          	__REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFMECCDATA0_REG     	__REG(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
+#define NFMECCDATA1_REG     	__REG(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
+#define NFSECCDATA0_REG      	__REG(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
+#define NFSBLK_REG          	__REG(ELFIN_NAND_BASE+NFSBLK_OFFSET)
+#define NFEBLK_REG           	__REG(ELFIN_NAND_BASE+NFEBLK_OFFSET)
+#define NFSTAT_REG           	__REG(ELFIN_NAND_BASE+NFSTAT_OFFSET)
+#define NFESTAT0_REG         	__REG(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
+#define NFESTAT1_REG         	__REG(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
+#define NFMECC0_REG          	__REG(ELFIN_NAND_BASE+NFMECC0_OFFSET)
+#define NFMECC1_REG          	__REG(ELFIN_NAND_BASE+NFMECC1_OFFSET)
+#define NFSECC_REG           	__REG(ELFIN_NAND_BASE+NFSECC_OFFSET)
+#define NFMLCBITPT_REG         	__REG(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
+
+#define NFCONF_ECC_4BIT		(1<<24)
+
+#define NFCONT_ECC_ENC		(1<<18)
+#define NFCONT_WP		(1<<16)
+#define NFCONT_MECCLOCK		(1<<7)
+#define NFCONT_SECCLOCK		(1<<6)
+#define NFCONT_INITMECC		(1<<5)
+#define NFCONT_INITSECC		(1<<4)
+#define NFCONT_INITECC		(NFCONT_INITMECC | NFCONT_INITSECC)
+#define NFCONT_CS_ALT		(1<<2)
+#define NFCONT_CS		(1<<1)
+#define NFCONT_ENABLE		(1<<0)
+
+#define NFSTAT_ECCENCDONE	(1<<7)
+#define NFSTAT_ECCDECDONE	(1<<6)
+#define NFSTAT_RnB		(1<<0)
+
+#define NFESTAT0_ECCBUSY	(1<<31)
+
+/*
+ * Interrupt
+ */
+#define ELFIN_VIC0_BASE_ADDR	0x71200000
+#define ELFIN_VIC1_BASE_ADDR	0x71300000
+#define oINTMOD			0x0C  /* VIC INT SELECT (IRQ or FIQ) */
+#define oINTUNMSK		0x10  /* VIC INT EN (Unmask by writing 1) */
+#define oINTMSK			0x14  /* VIC INT EN CLEAR (Mask by writing 1) */
+#define oINTSUBMSK		0x1C  /* VIC SOFT INT CLEAR */
+#define oVECTADDR		0xF00 /* VIC ADDRESS */
+
+/*
+ * Watchdog timer
+ */
+#define ELFIN_WATCHDOG_BASE	0x7E004000
+
+#define WTCON_REG		__REG(0x7E004004)
+#define WTDAT_REG		__REG(0x7E004008)
+#define WTCNT_REG		__REG(0x7E00400C)
+
+
+/*
+ * UART
+ */
+#define ELFIN_UART_BASE		0x7F005000
+
+#define ELFIN_UART0_OFFSET	0x0000
+#define ELFIN_UART1_OFFSET	0x0400
+#define ELFIN_UART2_OFFSET	0x0800
+
+#define ULCON_OFFSET		0x00
+#define UCON_OFFSET		0x04
+#define UFCON_OFFSET		0x08
+#define UMCON_OFFSET		0x0C
+#define UTRSTAT_OFFSET		0x10
+#define UERSTAT_OFFSET		0x14
+#define UFSTAT_OFFSET		0x18
+#define UMSTAT_OFFSET		0x1C
+#define UTXH_OFFSET		0x20
+#define URXH_OFFSET		0x24
+#define UBRDIV_OFFSET		0x28
+#define UDIVSLOT_OFFSET		0x2C
+#define UINTP_OFFSET		0x30
+#define UINTSP_OFFSET		0x34
+#define UINTM_OFFSET		0x38
+
+#define ULCON0_REG		__REG(0x7F005000)
+#define UCON0_REG		__REG(0x7F005004)
+#define UFCON0_REG		__REG(0x7F005008)
+#define UMCON0_REG		__REG(0x7F00500C)
+#define UTRSTAT0_REG		__REG(0x7F005010)
+#define UERSTAT0_REG		__REG(0x7F005014)
+#define UFSTAT0_REG		__REG(0x7F005018)
+#define UMSTAT0_REG		__REG(0x7F00501c)
+#define UTXH0_REG		__REG(0x7F005020)
+#define URXH0_REG		__REG(0x7F005024)
+#define UBRDIV0_REG		__REG(0x7F005028)
+#define UDIVSLOT0_REG		__REG(0x7F00502c)
+#define UINTP0_REG		__REG(0x7F005030)
+#define UINTSP0_REG		__REG(0x7F005034)
+#define UINTM0_REG		__REG(0x7F005038)
+
+#define ULCON1_REG		__REG(0x7F005400)
+#define UCON1_REG		__REG(0x7F005404)
+#define UFCON1_REG		__REG(0x7F005408)
+#define UMCON1_REG		__REG(0x7F00540C)
+#define UTRSTAT1_REG		__REG(0x7F005410)
+#define UERSTAT1_REG		__REG(0x7F005414)
+#define UFSTAT1_REG		__REG(0x7F005418)
+#define UMSTAT1_REG		__REG(0x7F00541c)
+#define UTXH1_REG		__REG(0x7F005420)
+#define URXH1_REG		__REG(0x7F005424)
+#define UBRDIV1_REG		__REG(0x7F005428)
+#define UDIVSLOT1_REG		__REG(0x7F00542c)
+#define UINTP1_REG		__REG(0x7F005430)
+#define UINTSP1_REG		__REG(0x7F005434)
+#define UINTM1_REG		__REG(0x7F005438)
+
+#define UTRSTAT_TX_EMPTY	(1 << 2)
+#define UTRSTAT_RX_READY	(1 << 0)
+#define UART_ERR_MASK		0xF
+
+/*
+ * PWM timer
+ */
+#define ELFIN_TIMER_BASE       0x7F006000
+
+#define TCFG0_REG              __REG(0x7F006000)
+#define TCFG1_REG              __REG(0x7F006004)
+#define TCON_REG               __REG(0x7F006008)
+#define TCNTB0_REG             __REG(0x7F00600c)
+#define TCMPB0_REG             __REG(0x7F006010)
+#define TCNTO0_REG             __REG(0x7F006014)
+#define TCNTB1_REG             __REG(0x7F006018)
+#define TCMPB1_REG             __REG(0x7F00601c)
+#define TCNTO1_REG             __REG(0x7F006020)
+#define TCNTB2_REG             __REG(0x7F006024)
+#define TCMPB2_REG             __REG(0x7F006028)
+#define TCNTO2_REG             __REG(0x7F00602c)
+#define TCNTB3_REG             __REG(0x7F006030)
+#define TCMPB3_REG             __REG(0x7F006034)
+#define TCNTO3_REG             __REG(0x7F006038)
+#define TCNTB4_REG             __REG(0x7F00603c)
+#define TCNTO4_REG             __REG(0x7F006040)
+
+/* Fields */
+#define fTCFG0_DZONE           Fld(8, 16) /* the dead zone length (= timer 0) */
+#define fTCFG0_PRE1            Fld(8, 8)  /* prescaler value for time 2,3,4 */
+#define fTCFG0_PRE0            Fld(8, 0)  /* prescaler value for time 0,1 */
+#define fTCFG1_MUX4            Fld(4, 16)
+/* bits */
+#define TCFG0_DZONE(x)         FInsrt((x), fTCFG0_DZONE)
+#define TCFG0_PRE1(x)          FInsrt((x), fTCFG0_PRE1)
+#define TCFG0_PRE0(x)          FInsrt((x), fTCFG0_PRE0)
+#define TCON_4_AUTO            (1 << 22)  /* auto reload on/off for Timer 4 */
+#define TCON_4_UPDATE          (1 << 21)  /* manual Update TCNTB4 */
+#define TCON_4_ONOFF           (1 << 20)  /* 0: Stop, 1: start Timer 4 */
+#define COUNT_4_ON             (TCON_4_ONOFF * 1)
+#define COUNT_4_OFF            (TCON_4_ONOFF * 0)
+#define TCON_3_AUTO            (1 << 19)  /* auto reload on/off for Timer 3 */
+#define TIMER3_ATLOAD_ON       (TCON_3_AUTO * 1)
+#define TIMER3_ATLAOD_OFF      FClrBit(TCON, TCON_3_AUTO)
+#define TCON_3_INVERT          (1 << 18)  /* 1: Inverter on for TOUT3 */
+#define TIMER3_IVT_ON          (TCON_3_INVERT * 1)
+#define TIMER3_IVT_OFF         (FClrBit(TCON, TCON_3_INVERT))
+#define TCON_3_MAN             (1 << 17)  /* manual Update TCNTB3,TCMPB3 */
+#define TIMER3_MANUP           (TCON_3_MAN*1)
+#define TIMER3_NOP             (FClrBit(TCON, TCON_3_MAN))
+#define TCON_3_ONOFF           (1 << 16)  /* 0: Stop, 1: start Timer 3 */
+#define TIMER3_ON              (TCON_3_ONOFF * 1)
+#define TIMER3_OFF             (FClrBit(TCON, TCON_3_ONOFF))
+
+#if defined(CONFIG_CLK_400_100_50)
+#define Startup_AMDIV		400
+#define Startup_MDIV		400
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_400_133_66)
+#define Startup_AMDIV		400
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_533_133_66)
+#define Startup_AMDIV		533
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_667_133_66)
+#define Startup_AMDIV		667
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#endif
+
+#define	Startup_PCLKdiv		3
+#define Startup_HCLKx2div	1
+#define Startup_HCLKdiv		1
+#define Startup_MPLLdiv		1
+#define Startup_APLLdiv		0
+
+#define CLK_DIV_VAL	((Startup_PCLKdiv << 12) | (Startup_HCLKx2div << 9)| \
+	(Startup_HCLKdiv << 8) | (Startup_MPLLdiv<<4) | Startup_APLLdiv)
+#define MPLL_VAL	((1 << 31) | (Startup_MDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_MPLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_MDIV)
+
+#if defined(CONFIG_SYNC_MODE)
+#define APLL_VAL	((1 << 31) | (Startup_MDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_APLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_MDIV)
+#define Startup_HCLK	(Startup_MPLL / (Startup_HCLKx2div + 1) / \
+	(Startup_HCLKdiv + 1))
+#else
+#define APLL_VAL	((1 << 31) | (Startup_AMDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_APLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_AMDIV)
+#define Startup_HCLK	(Startup_MPLL / (Startup_HCLKx2div + 1) / \
+	(Startup_HCLKdiv + 1))
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define DMC1_MEM_CFG	0x80010012	/* Chip1, Burst4, Row/Column bit */
+#define DMC1_MEM_CFG2	0xB45
+#define DMC1_CHIP0_CFG	0x150F8		/* 0x4000_0000 ~ 0x43ff_ffff (64MB) */
+#define DMC_DDR_32_CFG	0x0 		/* 32bit, DDR */
+
+/* Memory Parameters */
+/* DDR Parameters */
+#define DDR_tREFRESH		7800	/* ns */
+#define DDR_tRAS		45	/* ns (min: 45ns)*/
+#define DDR_tRC 		68	/* ns (min: 67.5ns)*/
+#define DDR_tRCD		23	/* ns (min: 22.5ns)*/
+#define DDR_tRFC		80	/* ns (min: 80ns)*/
+#define DDR_tRP 		23	/* ns (min: 22.5ns)*/
+#define DDR_tRRD		15	/* ns (min: 15ns)*/
+#define DDR_tWR 		15	/* ns (min: 15ns)*/
+#define DDR_tXSR		120	/* ns (min: 120ns)*/
+#define DDR_CASL		3	/* CAS Latency 3 */
+
+/*
+ * mDDR memory configuration
+ */
+#define DMC_DDR_BA_EMRS 	2
+#define DMC_DDR_MEM_CASLAT	3
+#define DMC_DDR_CAS_LATENCY	(DDR_CASL << 1)					/* 6   Set Cas Latency to 3 */
+#define DMC_DDR_t_DQSS		1						/* Min 0.75 ~ 1.25 */
+#define DMC_DDR_t_MRD		2						/* Min 2 tck */
+#define DMC_DDR_t_RAS		(((Startup_HCLK/1000*DDR_tRAS)-1)/1000000+1)	/* 7, Min 45ns */
+#define DMC_DDR_t_RC		(((Startup_HCLK/1000*DDR_tRC)-1)/1000000+1) 	/* 10, Min 67.5ns */
+#define DMC_DDR_t_RCD		(((Startup_HCLK/1000*DDR_tRCD)-1)/1000000+1) 	/* 4,5(TRM), Min 22.5ns */
+#define DMC_DDR_schedule_RCD	((DMC_DDR_t_RCD - 3) << 3)
+#define DMC_DDR_t_RFC		(((Startup_HCLK/1000*DDR_tRFC)-1)/1000000+1) 	/* 11,18(TRM) Min 80ns */
+#define DMC_DDR_schedule_RFC	((DMC_DDR_t_RFC - 3) << 5)
+#define DMC_DDR_t_RP		(((Startup_HCLK/1000*DDR_tRP)-1)/1000000+1) 	/* 4, 5(TRM) Min 22.5ns */
+#define DMC_DDR_schedule_RP	((DMC_DDR_t_RP - 3) << 3)
+#define DMC_DDR_t_RRD		(((Startup_HCLK/1000*DDR_tRRD)-1)/1000000+1)	/* 3, Min 15ns */
+#define DMC_DDR_t_WR		(((Startup_HCLK/1000*DDR_tWR)-1)/1000000+1)	/* Min 15ns */
+#define DMC_DDR_t_WTR		2
+#define DMC_DDR_t_XP		2						/* 1tck + tIS(1.5ns) */
+#define DMC_DDR_t_XSR		(((Startup_HCLK/1000*DDR_tXSR)-1)/1000000+1)	/* 17, Min 120ns */
+#define DMC_DDR_t_ESR		DMC_DDR_t_XSR
+#define DMC_DDR_REFRESH_PRD	(((Startup_HCLK/1000*DDR_tREFRESH)-1)/1000000) 	/* TRM 2656 */
+#define DMC_DDR_USER_CONFIG	1						/* 2b01 : mDDR */
+
+#ifndef __ASSEMBLY__
+enum s3c64xx_uarts_nr {
+	S3C64XX_UART0,
+	S3C64XX_UART1,
+	S3C64XX_UART2,
+};
+
+#include "s3c64x0.h"
+
+static inline s3c64xx_uart *s3c64xx_get_base_uart(enum s3c64xx_uarts_nr nr)
+{
+	return (s3c64xx_uart *)(ELFIN_UART_BASE + (nr * 0x400));
+}
+#endif
+
+#endif /*__S3C6400_H__*/
diff --git a/include/s3c64x0.h b/include/s3c64x0.h
new file mode 100644
index 0000000..ba6802a
--- /dev/null
+++ b/include/s3c64x0.h
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2003
+ * David M??ller ELSOFT AG Switzerland. d.mueller at elsoft.ch
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+ */
+
+/************************************************
+ * NAME	    : S3C64XX.h
+ * Version  : 31.3.2003
+ *
+ * common stuff for SAMSUNG S3C64XX SoC
+ ************************************************/
+
+#ifndef __S3C64XX_H__
+#define __S3C64XX_H__
+
+#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400)
+#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your configuration!
+#endif
+
+typedef vu_char		S3C64XX_REG8;
+typedef vu_short	S3C64XX_REG16;
+typedef vu_long		S3C64XX_REG32;
+
+/* UART (see manual chapter 11) */
+typedef struct {
+	S3C64XX_REG32	ULCON;
+	S3C64XX_REG32	UCON;
+	S3C64XX_REG32	UFCON;
+	S3C64XX_REG32	UMCON;
+	S3C64XX_REG32	UTRSTAT;
+	S3C64XX_REG32	UERSTAT;
+	S3C64XX_REG32	UFSTAT;
+	S3C64XX_REG32	UMSTAT;
+#ifdef __BIG_ENDIAN
+	S3C64XX_REG8	res1[3];
+	S3C64XX_REG8	UTXH;
+	S3C64XX_REG8	res2[3];
+	S3C64XX_REG8	URXH;
+#else /* Little Endian */
+	S3C64XX_REG8	UTXH;
+	S3C64XX_REG8	res1[3];
+	S3C64XX_REG8	URXH;
+	S3C64XX_REG8	res2[3];
+#endif
+	S3C64XX_REG32	UBRDIV;
+#ifdef __BIG_ENDIAN
+	S3C64XX_REG8	res3[2];
+	S3C64XX_REG16	UDIVSLOT;
+#else
+	S3C64XX_REG16	UDIVSLOT;
+	S3C64XX_REG8	res3[2];
+#endif
+} /*__attribute__((__packed__))*/ s3c64xx_uart;
+
+/* PWM TIMER (see manual chapter 10) */
+typedef struct {
+	S3C64XX_REG32	TCNTB;
+	S3C64XX_REG32	TCMPB;
+	S3C64XX_REG32	TCNTO;
+} /*__attribute__((__packed__))*/ s3c64xx_timer;
+
+typedef struct {
+	S3C64XX_REG32	TCFG0;
+	S3C64XX_REG32	TCFG1;
+	S3C64XX_REG32	TCON;
+	s3c64xx_timer	ch[4];
+	S3C64XX_REG32	TCNTB4;
+	S3C64XX_REG32	TCNTO4;
+} /*__attribute__((__packed__))*/ s3c64xx_timers;
+
+#endif /*__S3C64XX_H__*/
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 4/7 v2] USB: Add support for OHCI controller on s3c6400
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
                           ` (2 preceding siblings ...)
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 3/7 v2] ARM: Add arm1176 core with s3c6400 SoC Guennadi Liakhovetski
@ 2008-08-04 10:43         ` Guennadi Liakhovetski
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 5/7 v2] serial: add s3c64xx serial driver Guennadi Liakhovetski
                           ` (4 subsequent siblings)
  8 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:43 UTC (permalink / raw)
  To: u-boot

Notice: USB on s3c6400 currently works _only_ with switched off MMU. One could
try to enable the MMU, but map addresses 1-to-1, and disable data cache, then
it should work too and we could still profit from instruction cache.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 cpu/arm1176/s3c64xx/Makefile |    1 +
 cpu/arm1176/s3c64xx/usb.c    |   45 ++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/usb_ohci.c       |    1 +
 3 files changed, 47 insertions(+), 0 deletions(-)
 create mode 100644 cpu/arm1176/s3c64xx/usb.c

diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile
index 66ac4aa..8cee691 100644
--- a/cpu/arm1176/s3c64xx/Makefile
+++ b/cpu/arm1176/s3c64xx/Makefile
@@ -27,6 +27,7 @@ LIB	= $(obj)lib$(SOC).a
 
 COBJS-y	= interrupts.o
 COBJS-$(CONFIG_S3C6400)	+= cpu_init.o speed.o
+COBJS-$(CONFIG_USB_OHCI_NEW) += usb.o
 
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
 
diff --git a/cpu/arm1176/s3c64xx/usb.c b/cpu/arm1176/s3c64xx/usb.c
new file mode 100644
index 0000000..274a4ed
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/usb.c
@@ -0,0 +1,45 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) initialization for USB on the S3C64XX.
+ *
+ * Copyright (C) 2008,
+ * Guennadi Liakhovetski, DENX Software Engineering <lg@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 <common.h>
+#include <s3c6400.h>
+
+int usb_cpu_init(void)
+{
+	OTHERS_REG |= 0x10000;
+	return 0;
+}
+
+int usb_cpu_stop(void)
+{
+	OTHERS_REG &= ~0x10000;
+	return 0;
+}
+
+void usb_cpu_init_fail(void)
+{
+	OTHERS_REG &= ~0x10000;
+}
diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c
index fd60edb..0bfa4d7 100644
--- a/drivers/usb/usb_ohci.c
+++ b/drivers/usb/usb_ohci.c
@@ -69,6 +69,7 @@
 #if defined(CONFIG_ARM920T) || \
     defined(CONFIG_S3C2400) || \
     defined(CONFIG_S3C2410) || \
+    defined(CONFIG_S3C6400) || \
     defined(CONFIG_440EP) || \
     defined(CONFIG_PCI_OHCI) || \
     defined(CONFIG_MPC5200) || \
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 5/7 v2] serial: add s3c64xx serial driver
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
                           ` (3 preceding siblings ...)
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 4/7 v2] USB: Add support for OHCI controller on s3c6400 Guennadi Liakhovetski
@ 2008-08-04 10:43         ` Guennadi Liakhovetski
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 6/7 v2] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
                           ` (3 subsequent siblings)
  8 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:43 UTC (permalink / raw)
  To: u-boot

Ported from u-boot-1.1.6 driver by Samsung.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 drivers/serial/Makefile  |    1 +
 drivers/serial/s3c64xx.c |  186 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 187 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/s3c64xx.c

diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index c9e797e..2a11ae5 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -30,6 +30,7 @@ COBJS-y += mcfuart.o
 COBJS-y += ns9750_serial.o
 COBJS-y += ns16550.o
 COBJS-y += s3c4510b_uart.o
+COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
 COBJS-y += serial.o
 COBJS-y += serial_max3100.o
 COBJS-y += serial_pl010.o
diff --git a/drivers/serial/s3c64xx.c b/drivers/serial/s3c64xx.c
new file mode 100644
index 0000000..1763bc3
--- /dev/null
+++ b/drivers/serial/s3c64xx.c
@@ -0,0 +1,186 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * 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 <s3c6400.h>
+
+#ifdef CONFIG_SERIAL1
+#define UART_NR	S3C64XX_UART0
+
+#elif defined(CONFIG_SERIAL2)
+#define UART_NR	S3C64XX_UART1
+
+#elif defined(CONFIG_SERIAL3)
+#define UART_NR	S3C64XX_UART2
+
+#else
+#error "Bad: you didn't configure serial ..."
+#endif
+
+#define barrier() asm volatile("" ::: "memory")
+
+/* See table in 31.6.11 */
+static const int udivslot[] = {
+	0,
+	0x0080,
+	0x0808,
+	0x0888,
+	0x2222,
+	0x4924,
+	0x4a52,
+	0x54aa,
+	0x5555,
+	0xd555,
+	0xd5d5,
+	0xddd5,
+	0xdddd,
+	0xdfdd,
+	0xdfdf,
+	0xffdf,
+};
+
+void serial_setbrg(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+	u32 reg, pclk_ratio = get_PCLK() / gd->baudrate;
+	int i;
+
+	/* PCLK / (16 * baudrate) - 1 */
+	reg = pclk_ratio / 16 - 1;
+	i = pclk_ratio - (reg + 1) * 16;
+
+	uart->UBRDIV = reg;
+	uart->UDIVSLOT = udivslot[i];
+
+	for (i = 0; i < 100; i++)
+		barrier();
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init(void)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+	/* reset and enable FIFOs, set triggers to the maximum */
+	uart->UFCON = 0xff;
+	uart->UMCON = 0;
+	/* 8N1 */
+	uart->ULCON = 3;
+	/* No interrupts, no DMA, pure polling */
+	uart->UCON = 5;
+
+	serial_setbrg();
+
+	return 0;
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc(void)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+	/* wait for character to arrive */
+	while (!(uart->UTRSTAT & 0x1));
+
+	return uart->URXH & 0xff;
+}
+
+#ifdef CONFIG_HWFLOW
+static int hwflow = 0;		/* turned off by default */
+int hwflow_onoff(int on)
+{
+	switch (on) {
+	case 1:
+		hwflow = 1;	/* turn on */
+		break;
+	case -1:
+		hwflow = 0;	/* turn off */
+		break;
+	}
+	return hwflow;
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int be_quiet;
+void disable_putc(void)
+{
+	be_quiet = 1;
+}
+
+void enable_putc(void)
+{
+	be_quiet = 0;
+}
+#endif
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc(const char c)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+#ifdef CONFIG_MODEM_SUPPORT
+	if (be_quiet)
+		return;
+#endif
+
+	/* wait for room in the tx FIFO */
+	while (!(uart->UTRSTAT & 0x2));
+
+#ifdef CONFIG_HWFLOW
+	/* Wait for CTS up */
+	while (hwflow && !(uart->UMSTAT & 0x1));
+#endif
+
+	uart->UTXH = c;
+
+	/* If \n, also do \r */
+	if (c == '\n')
+		serial_putc('\r');
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int serial_tstc(void)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+	return uart->UTRSTAT & 0x1;
+}
+
+void serial_puts(const char *s)
+{
+	while (*s)
+		serial_putc(*s++);
+}
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 6/7 v2] NAND: add NAND driver for s3c64xx
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
                           ` (4 preceding siblings ...)
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 5/7 v2] serial: add s3c64xx serial driver Guennadi Liakhovetski
@ 2008-08-04 10:43         ` Guennadi Liakhovetski
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 7/7 v2] ARM: Add support for S3C6400 based SMDK6400 board Guennadi Liakhovetski
                           ` (2 subsequent siblings)
  8 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:43 UTC (permalink / raw)
  To: u-boot

Ported from u-boot-1.1.6 driver by Samsung.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 drivers/mtd/nand/Makefile  |    1 +
 drivers/mtd/nand/s3c64xx.c |  307 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 308 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/s3c64xx.c

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 7bd22a0..236cf03 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -33,6 +33,7 @@ COBJS-y += nand_bbt.o
 COBJS-y += nand_util.o
 
 COBJS-y += fsl_upm.o
+COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c
new file mode 100644
index 0000000..f2211f7
--- /dev/null
+++ b/drivers/mtd/nand/s3c64xx.c
@@ -0,0 +1,307 @@
+/*
+ * (C) Copyright 2006 DENX Software Engineering
+ *
+ * Implementation for U-Boot 1.1.6 by Samsung
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
+
+#include <nand.h>
+#include <s3c6400.h>
+
+#include <asm/io.h>
+
+#ifdef CONFIG_NAND_SPL
+#define printf(arg...) do {} while (0)
+#endif
+
+/* Nand flash definition values by jsgood */
+#ifdef S3C_NAND_DEBUG
+/*
+ * Function to print out oob buffer for debugging
+ * Written by jsgood
+ */
+static void print_oob(const char *header, struct mtd_info *mtd)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	printf("%s:\t", header);
+
+	for(i = 0; i < 64; i++)
+		printf("%02x ", chip->oob_poi[i]);
+
+	printf("\n");
+}
+#endif /* S3C_NAND_DEBUG */
+
+#ifdef CONFIG_NAND_SPL
+static u_char nand_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	return readb(this->IO_ADDR_R);
+}
+
+static void nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+	struct nand_chip *this = mtd->priv;
+	writeb(byte, this->IO_ADDR_W);
+}
+
+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i = 0; i < len; i++)
+		buf[i] = readb(this->IO_ADDR_R);
+}
+#endif
+
+static void s3c_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	int ctrl = readl(NFCONT);
+
+	switch (chip) {
+	case -1:
+		ctrl |= 6;
+		break;
+	case 0:
+		ctrl &= ~2;
+		break;
+	case 1:
+		ctrl &= ~4;
+		break;
+	default:
+		return;
+	}
+
+	writel(ctrl, NFCONT);
+}
+
+/*
+ * Hardware specific access to control-lines function
+ * Written by jsgood
+ */
+static void s3c_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	struct nand_chip *this = mtd->priv;
+
+	switch (cmd) {
+	case NAND_CTL_SETCLE:
+		this->IO_ADDR_W = (void __iomem *)NFCMMD;
+		break;
+	case NAND_CTL_CLRCLE:
+		this->IO_ADDR_W = (void __iomem *)NFDATA;
+		break;
+	case NAND_CTL_SETALE:
+		this->IO_ADDR_W = (void __iomem *)NFADDR;
+		break;
+	case NAND_CTL_CLRALE:
+		this->IO_ADDR_W = (void __iomem *)NFDATA;
+		break;
+	case NAND_CTL_SETNCE:
+		s3c_nand_select_chip(mtd, 0);
+		break;
+	case NAND_CTL_CLRNCE:
+		s3c_nand_select_chip(mtd, -1);
+		break;
+	}
+}
+
+/*
+ * Function for checking device ready pin
+ * Written by jsgood
+ */
+static int s3c_nand_device_ready(struct mtd_info *mtdinfo)
+{
+	while (!(readl(NFSTAT) & NFSTAT_RnB)) {}
+	return 1;
+}
+
+#ifdef CFG_S3C_NAND_HWECC
+/*
+ * This function is called before encoding ecc codes to ready ecc engine.
+ * Written by jsgood
+ */
+static void s3c_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	u_long nfcont, nfconf;
+
+	/*
+	 * The original driver used 4-bit ECC for "new" MLC chips, i.e., for
+	 * those with non-zero ID[3][3:2], which anyway only holds for ST
+	 * (Numonyx) chips
+	 */
+	nfconf = readl(NFCONF) & ~NFCONF_ECC_4BIT;
+
+	writel(nfconf, NFCONF);
+
+	/* Initialize & unlock */
+	nfcont = readl(NFCONT);
+	nfcont |= NFCONT_INITECC;
+	nfcont &= ~NFCONT_MECCLOCK;
+
+	if (mode == NAND_ECC_WRITE)
+		nfcont |= NFCONT_ECC_ENC;
+	else if (mode == NAND_ECC_READ)
+		nfcont &= ~NFCONT_ECC_ENC;
+
+	writel(nfcont, NFCONT);
+}
+
+/*
+ * This function is called immediately after encoding ecc codes.
+ * This function returns encoded ecc codes.
+ * Written by jsgood
+ */
+static int s3c_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+				  u_char *ecc_code)
+{
+	u_long nfcont, nfmecc0;
+
+	/* Lock */
+	nfcont = readl(NFCONT);
+	nfcont |= NFCONT_MECCLOCK;
+	writel(nfcont, NFCONT);
+
+	nfmecc0 = readl(NFMECC0);
+
+	ecc_code[0] = nfmecc0 & 0xff;
+	ecc_code[1] = (nfmecc0 >> 8) & 0xff;
+	ecc_code[2] = (nfmecc0 >> 16) & 0xff;
+	ecc_code[3] = (nfmecc0 >> 24) & 0xff;
+
+	return 0;
+}
+
+/*
+ * This function determines whether read data is good or not.
+ * If SLC, must write ecc codes to controller before reading status bit.
+ * If MLC, status bit is already set, so only reading is needed.
+ * If status bit is good, return 0.
+ * If correctable errors occured, do that.
+ * If uncorrectable errors occured, return -1.
+ * Written by jsgood
+ */
+static int s3c_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+				 u_char *read_ecc, u_char *calc_ecc)
+{
+	int ret = -1;
+	u_long nfestat0, nfmeccdata0, nfmeccdata1, err_byte_addr;
+	u_char err_type, repared;
+
+	/* SLC: Write ecc to compare */
+	nfmeccdata0 = (calc_ecc[1] << 16) | calc_ecc[0];
+	nfmeccdata1 = (calc_ecc[3] << 16) | calc_ecc[2];
+	writel(nfmeccdata0, NFMECCDATA0);
+	writel(nfmeccdata1, NFMECCDATA1);
+
+	/* Read ecc status */
+	nfestat0 = readl(NFESTAT0);
+	err_type = nfestat0 & 0x3;
+
+	switch (err_type) {
+	case 0: /* No error */
+		ret = 0;
+		break;
+
+	case 1:
+		/*
+		 * 1 bit error (Correctable)
+		 * (nfestat0 >> 7) & 0x7ff	:error byte number
+		 * (nfestat0 >> 4) & 0x7	:error bit number
+		 */
+		err_byte_addr = (nfestat0 >> 7) & 0x7ff;
+		repared = dat[err_byte_addr] ^ (1 << ((nfestat0 >> 4) & 0x7));
+
+		printf("S3C NAND: 1 bit error detected at byte %ld. "
+		       "Correcting from 0x%02x to 0x%02x...OK\n",
+		       err_byte_addr, dat[err_byte_addr], repared);
+
+		dat[err_byte_addr] = repared;
+
+		ret = 1;
+		break;
+
+	case 2: /* Multiple error */
+	case 3: /* ECC area error */
+		printf("S3C NAND: ECC uncorrectable error detected. "
+		       "Not correctable.\n");
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+#endif /* CFG_S3C_NAND_HWECC */
+
+/*
+ * Board-specific NAND initialization. The following members of the
+ * argument are board-specific (per include/linux/mtd/nand.h):
+ * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
+ * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
+ * - hwcontrol: hardwarespecific function for accesing control-lines
+ * - dev_ready: hardwarespecific function for  accesing device ready/busy line
+ * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
+ *   only be provided if a hardware ECC is available
+ * - eccmode: mode of ecc, see defines
+ * - chip_delay: chip dependent delay for transfering data from array to
+ *   read regs (tR)
+ * - options: various chip options. They can partly be set to inform
+ *   nand_scan about special functionality. See the defines for further
+ *   explanation
+ * Members with a "?" were not set in the merged testing-NAND branch,
+ * so they are not set here either.
+ */
+int board_nand_init(struct nand_chip *nand)
+{
+	NFCONT_REG 		= (NFCONT_REG & ~NFCONT_WP) | NFCONT_ENABLE | 0x6;
+
+	nand->IO_ADDR_R		= (void __iomem *)NFDATA;
+	nand->IO_ADDR_W		= (void __iomem *)NFDATA;
+	nand->hwcontrol		= s3c_nand_hwcontrol;
+	nand->dev_ready		= s3c_nand_device_ready;
+	nand->select_chip	= s3c_nand_select_chip;
+	nand->options		= 0;
+#ifdef CONFIG_NAND_SPL
+	nand->read_byte		= nand_read_byte;
+	nand->write_byte	= nand_write_byte;
+	nand->read_buf		= nand_read_buf;
+#endif
+
+#ifdef CFG_S3C_NAND_HWECC
+	nand->enable_hwecc	= s3c_nand_enable_hwecc;
+	nand->calculate_ecc	= s3c_nand_calculate_ecc;
+	nand->correct_data	= s3c_nand_correct_data;
+
+	/* A shot in the dark, I don't know how to use this smart ECC-mode
+	 * selection with the current driver */
+	nand->eccmode		= NAND_ECC_HW12_2048;
+#else
+	nand->eccmode		= NAND_ECC_SOFT;
+#endif /* ! CFG_S3C_NAND_HWECC */
+
+	return 0;
+}
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 7/7 v2] ARM: Add support for S3C6400 based SMDK6400 board
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
                           ` (5 preceding siblings ...)
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 6/7 v2] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
@ 2008-08-04 10:43         ` Guennadi Liakhovetski
  2008-08-04 11:00         ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Wolfgang Denk
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
  8 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 10:43 UTC (permalink / raw)
  To: u-boot

SMDK6400 can only boot U-Boot from NAND-flash. This patch adds a nand_spl 
driver for it too. The board can also boot from the NOR flash, but due to 
hardware limitations it can only address 64KiB on it, which is not enough 
for U-Boot. Ported from u-boot-1.1.6 version by Samsung.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 MAKEALL                                    |    1 +
 Makefile                                   |   17 ++
 board/samsung/smdk6400/Makefile            |   54 +++++
 board/samsung/smdk6400/config.mk           |   30 +++
 board/samsung/smdk6400/lowlevel_init.S     |  316 ++++++++++++++++++++++++++++
 board/samsung/smdk6400/smdk6400.c          |  130 ++++++++++++
 board/samsung/smdk6400/u-boot-nand.lds     |   62 ++++++
 include/configs/smdk6400.h                 |  304 ++++++++++++++++++++++++++
 nand_spl/board/samsung/smdk6400/Makefile   |  106 ++++++++++
 nand_spl/board/samsung/smdk6400/config.mk  |   40 ++++
 nand_spl/board/samsung/smdk6400/u-boot.lds |   61 ++++++
 11 files changed, 1121 insertions(+), 0 deletions(-)
 create mode 100644 board/samsung/smdk6400/Makefile
 create mode 100644 board/samsung/smdk6400/config.mk
 create mode 100644 board/samsung/smdk6400/lowlevel_init.S
 create mode 100644 board/samsung/smdk6400/smdk6400.c
 create mode 100644 board/samsung/smdk6400/u-boot-nand.lds
 create mode 100644 include/configs/smdk6400.h
 create mode 100644 nand_spl/board/samsung/smdk6400/Makefile
 create mode 100644 nand_spl/board/samsung/smdk6400/config.mk
 create mode 100644 nand_spl/board/samsung/smdk6400/u-boot.lds

diff --git a/MAKEALL b/MAKEALL
index ee83cca..a3ed47d 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -515,6 +515,7 @@ LIST_ARM11="		\
 	imx31_litekit	\
 	imx31_phycore	\
 	mx31ads		\
+	smdk6400	\
 "
 
 #########################################################################
diff --git a/Makefile b/Makefile
index b104617..0c5b8a6 100644
--- a/Makefile
+++ b/Makefile
@@ -2677,6 +2677,23 @@ mx31ads_config		: unconfig
 omap2420h4_config	: unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4 NULL omap24xx
 
+#########################################################################
+## ARM1176 Systems
+#########################################################################
+smdk6400_noUSB_config	\
+smdk6400_config	:	unconfig
+	@mkdir -p $(obj)include $(obj)board/samsung/smdk6400
+	@mkdir -p $(obj)nand_spl/board/samsung/smdk6400
+	@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
+	@if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then			\
+		echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
+		$(MKCONFIG) $(@:_config=) arm arm1176 smdk6400 samsung s3c64xx;		\
+	else										\
+		echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
+		$(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6400 samsung s3c64xx;	\
+	fi
+	@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
+
 #========================================================================
 # i386
 #========================================================================
diff --git a/board/samsung/smdk6400/Makefile b/board/samsung/smdk6400/Makefile
new file mode 100644
index 0000000..d35dc8b
--- /dev/null
+++ b/board/samsung/smdk6400/Makefile
@@ -0,0 +1,54 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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	:= smdk6400.o
+SOBJS	:= lowlevel_init.o
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+#.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+#		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/samsung/smdk6400/config.mk b/board/samsung/smdk6400/config.mk
new file mode 100644
index 0000000..298d387
--- /dev/null
+++ b/board/samsung/smdk6400/config.mk
@@ -0,0 +1,30 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+#
+# SAMSUNG SMDK6400 board with mDirac3 (ARM1176) cpu
+#
+# see http://www.samsung.com/ for more information on SAMSUNG
+
+# On SMDK6400 we use the 64 MB SDRAM bank at
+#
+# 0x50000000 to 0x58000000
+#
+# Linux-Kernel is expected to be at 0x50008000, entry 0x50008000
+#
+# we load ourselves to 0x57e00000 without MMU
+# with MMU, load address is changed to 0xc7e00000
+#
+# download area is 0x5000c000
+
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+
+ifndef CONFIG_NAND_SPL
+TEXT_BASE = $(RAM_TEXT)
+else
+TEXT_BASE = 0
+endif
diff --git a/board/samsung/smdk6400/lowlevel_init.S b/board/samsung/smdk6400/lowlevel_init.S
new file mode 100644
index 0000000..034c810
--- /dev/null
+++ b/board/samsung/smdk6400/lowlevel_init.S
@@ -0,0 +1,316 @@
+/*
+ * 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@elsoft.ch>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <config.h>
+#include <version.h>
+
+#include <s3c6400.h>
+
+#ifdef CONFIG_SERIAL1
+#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET)
+#elif defined(CONFIG_SERIAL2)
+#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET)
+#else
+#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART2_OFFSET)
+#endif
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+	.globl lowlevel_init
+lowlevel_init:
+	mov	r12, lr
+
+	/* LED on only #8 */
+	ldr	r0, =ELFIN_GPIO_BASE
+	ldr	r1, =0x55540000
+	str	r1, [r0, #GPNCON_OFFSET]
+
+	ldr	r1, =0x55555555
+	str	r1, [r0, #GPNPUD_OFFSET]
+
+	ldr	r1, =0xf000
+	str	r1, [r0, #GPNDAT_OFFSET]
+
+	/* Disable Watchdog */
+	ldr	r0, =0x7e000000		@0x7e004000
+	orr	r0, r0, #0x4000
+	mov	r1, #0
+	str	r1, [r0]
+
+	/* External interrupt pending clear */
+	ldr	r0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET)	/*EINTPEND*/
+	ldr	r1, [r0]
+	str	r1, [r0]
+
+	ldr	r0, =ELFIN_VIC0_BASE_ADDR 	@0x71200000
+	ldr	r1, =ELFIN_VIC1_BASE_ADDR 	@0x71300000
+
+	/* Disable all interrupts (VIC0 and VIC1) */
+	mvn	r3, #0x0
+	str	r3, [r0, #oINTMSK]
+	str	r3, [r1, #oINTMSK]
+
+	/* Set all interrupts as IRQ */
+	mov	r3, #0x0
+	str	r3, [r0, #oINTMOD]
+	str	r3, [r1, #oINTMOD]
+
+	/* Pending Interrupt Clear */
+	mov	r3, #0x0
+	str	r3, [r0, #oVECTADDR]
+	str	r3, [r1, #oVECTADDR]
+
+	/* init system clock */
+	bl system_clock_init
+
+#ifndef CONFIG_NAND_SPL
+	/* for UART */
+	bl uart_asm_init
+#endif
+
+#ifdef CONFIG_BOOT_NAND
+	/* simple init for NAND */
+	bl nand_asm_init
+#endif
+
+	bl	mem_ctrl_asm_init
+
+/* Wakeup support. Don't know if it's going to be used, untested. */
+        ldr     r0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET)
+        ldr     r1, [r0]
+        bic     r1, r1, #0xfffffff7
+        cmp     r1, #0x8
+        beq     wakeup_reset
+
+1:
+	mov	lr, r12
+	mov	pc, lr
+
+wakeup_reset:
+
+	/* Clear wakeup status register */
+	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET)
+	ldr	r1, [r0]
+	str	r1, [r0]
+
+        /* LED test */
+        ldr     r0, =ELFIN_GPIO_BASE
+        ldr     r1, =0x3000
+        str     r1, [r0, #GPNDAT_OFFSET]
+
+	/* Load return address and jump to kernel */
+	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET)
+	/* r1 = physical address of s3c6400_cpu_resume function */
+	ldr	r1, [r0]
+	/* Jump to kernel (sleep-s3c6400.S) */
+	mov	pc, r1
+	nop
+	nop
+/*
+ * system_clock_init: Initialize core clock and bus clock.
+ * void system_clock_init(void)
+ */
+system_clock_init:
+	ldr	r0, =ELFIN_CLOCK_POWER_BASE	/* 0x7e00f000 */
+
+#ifdef CONFIG_SYNC_MODE
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	mov	r2, #0x40
+	orr	r1, r1, r2
+	str	r1, [r0, #OTHERS_OFFSET]
+
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	ldr	r2, =0x80
+	orr	r1, r1, r2
+	str	r1, [r0, #OTHERS_OFFSET]
+
+check_syncack:
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	ldr	r2, =0xf00
+	and	r1, r1, r2
+	cmp	r1, #0xf00
+	bne	check_syncack
+#else	/* ASYNC Mode */
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/*
+	 * This was unconditional in original Samsung sources, but it doesn't
+	 * seem to make much sense on S3C6400.
+	 */
+#ifndef CONFIG_S3C6400
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	bic	r1, r1, #0xC0
+	orr	r1, r1, #0x40
+	str	r1, [r0, #OTHERS_OFFSET]
+
+wait_for_async:
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	and	r1, r1, #0xf00
+	cmp	r1, #0x0
+	bne	wait_for_async
+#endif
+
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	bic	r1, r1, #0x40
+	str	r1, [r0, #OTHERS_OFFSET]
+#endif
+
+	mov	r1, #0xff00
+	orr	r1, r1, #0xff
+	str	r1, [r0, #APLL_LOCK_OFFSET]
+	str	r1, [r0, #MPLL_LOCK_OFFSET]
+
+	/* Set Clock Divider */
+	ldr   	r1, [r0, #CLK_DIV0_OFFSET]
+	bic	r1, r1, #0x30000
+	bic	r1, r1, #0xff00
+	bic	r1, r1, #0xff
+	ldr	r2, =CLK_DIV_VAL
+	orr	r1, r1, r2
+	str	r1, [r0, #CLK_DIV0_OFFSET]
+
+	ldr	r1, =APLL_VAL
+	str	r1, [r0, #APLL_CON_OFFSET]
+	ldr	r1, =MPLL_VAL
+	str	r1, [r0, #MPLL_CON_OFFSET]
+
+	/* FOUT of EPLL is 96MHz */
+	ldr	r1, =0x200203
+	str	r1, [r0, #EPLL_CON0_OFFSET]
+	ldr	r1, =0x0
+	str	r1, [r0, #EPLL_CON1_OFFSET]
+
+	/* APLL, MPLL, EPLL select to Fout */
+	ldr	r1, [r0, #CLK_SRC_OFFSET]
+	orr	r1, r1, #0x7
+	str	r1, [r0, #CLK_SRC_OFFSET]
+
+	/* wait at least 200us to stablize all clock */
+	mov	r1, #0x10000
+1:	subs	r1, r1, #1
+	bne	1b
+
+	/* Synchronization for VIC port */
+#if defined(CONFIG_SYNC_MODE)
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	orr	r1, r1, #0x20
+	str	r1, [r0, #OTHERS_OFFSET]
+#elif !defined(CONFIG_S3C6400)
+	/* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	bic	r1, r1, #0x20
+	str	r1, [r0, #OTHERS_OFFSET]
+#endif
+	mov	pc, lr
+
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * uart_asm_init: Initialize UART's pins
+ */
+uart_asm_init:
+	/* set GPIO to enable UART */
+	ldr	r0, =ELFIN_GPIO_BASE
+	ldr	r1, =0x220022
+	str   	r1, [r0, #GPACON_OFFSET]
+	mov	pc, lr
+#endif
+
+#ifdef CONFIG_BOOT_NAND
+/*
+ * NAND Interface init for SMDK6400
+ */
+nand_asm_init:
+	ldr	r0, =ELFIN_NAND_BASE
+	ldr	r1, [r0, #NFCONF_OFFSET]
+	orr	r1, r1, #0x70
+	orr	r1, r1, #0x7700
+	str     r1, [r0, #NFCONF_OFFSET]
+
+	ldr	r1, [r0, #NFCONT_OFFSET]
+	orr	r1, r1, #0x07
+	str     r1, [r0, #NFCONT_OFFSET]
+
+	mov	pc, lr
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+/*
+ * MMU Table for SMDK6400
+ */
+
+	/* form a first-level section entry */
+.macro FL_SECTION_ENTRY base,ap,d,c,b
+	.word (\base << 20) | (\ap << 10) | \
+	      (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
+.endm
+
+.section .mmudata, "a"
+	.align 14
+	/* the following alignment creates the mmu table@address 0x4000. */
+	.globl mmu_table
+mmu_table:
+	.set __base, 0
+	/* 1:1 mapping for debugging */
+	.rept 0xA00
+	FL_SECTION_ENTRY __base, 3, 0, 0, 0
+	.set __base, __base + 1
+	.endr
+
+	/* access is not allowed. */
+	.rept 0xC00 - 0xA00
+	.word 0x00000000
+	.endr
+
+	/* 128MB for SDRAM 0xC0000000 -> 0x50000000 */
+	.set __base, 0x500
+	.rept 0xC80 - 0xC00
+	FL_SECTION_ENTRY __base, 3, 0, 1, 1
+	.set __base, __base + 1
+	.endr
+
+	/* access is not allowed. */
+	.rept 0x1000 - 0xc80
+	.word 0x00000000
+	.endr
+#endif
diff --git a/board/samsung/smdk6400/smdk6400.c b/board/samsung/smdk6400/smdk6400.c
new file mode 100644
index 0000000..77fd2c8
--- /dev/null
+++ b/board/samsung/smdk6400/smdk6400.c
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
+#include <s3c6400.h>
+
+/* ------------------------------------------------------------------------- */
+#define CS8900_Tacs	0x0	/* 0clk		address set-up		*/
+#define CS8900_Tcos	0x4	/* 4clk		chip selection set-up	*/
+#define CS8900_Tacc	0xE	/* 14clk	access cycle		*/
+#define CS8900_Tcoh	0x1	/* 1clk		chip selection hold	*/
+#define CS8900_Tah	0x4	/* 4clk		address holding time	*/
+#define CS8900_Tacp	0x6	/* 6clk		page mode access cycle	*/
+#define CS8900_PMC	0x0	/* normal(1data)page mode configuration	*/
+
+static inline void delay(unsigned long loops)
+{
+	__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+			  "bne 1b"
+			  : "=r" (loops) : "0" (loops));
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+static void cs8900_pre_init(void)
+{
+	SROM_BW_REG &= ~(0xf << 4);
+	SROM_BW_REG |= (1 << 7) | (1 << 6) | (1 << 4);
+	SROM_BC1_REG = ((CS8900_Tacs << 28) + (CS8900_Tcos << 24) +
+			(CS8900_Tacc << 16) + (CS8900_Tcoh << 12) +
+			(CS8900_Tah << 8) + (CS8900_Tacp << 4) + CS8900_PMC);
+}
+
+int board_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	cs8900_pre_init();
+
+	/* NOR-flash in SROM0 */
+
+	/* Enable WAIT */
+	SROM_BW_REG |= 4 | 8 | 1;
+
+	gd->bd->bi_arch_number = MACH_TYPE;
+	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+	printf("Board:   SMDK6400\n");
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+ulong virt_to_phy_smdk6400(ulong addr)
+{
+	if ((0xc0000000 <= addr) && (addr < 0xc8000000))
+		return addr - 0xc0000000 + 0x50000000;
+	else
+		printf("do not support this address : %08lx\n", addr);
+
+	return addr;
+}
+#endif
+
+#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
+#include <linux/mtd/nand.h>
+extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
+void nand_init(void)
+{
+	nand_probe(CFG_NAND_BASE);
+	if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN)
+		print_size(nand_dev_desc[0].totlen, "\n");
+}
+#endif
+
+ulong board_flash_get_legacy (ulong base, int banknum, flash_info_t *info)
+{
+	if (banknum == 0) {	/* non-CFI boot flash */
+		info->portwidth = FLASH_CFI_16BIT;
+		info->chipwidth = FLASH_CFI_BY16;
+		info->interface = FLASH_CFI_X16;
+		return 1;
+	} else
+		return 0;
+}
diff --git a/board/samsung/smdk6400/u-boot-nand.lds b/board/samsung/smdk6400/u-boot-nand.lds
new file mode 100644
index 0000000..132ab21
--- /dev/null
+++ b/board/samsung/smdk6400/u-boot-nand.lds
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm1176/start.o	(.text)
+	  cpu/arm1176/s3c64xx/cpu_init.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);
+	.mmudata : { *(.mmudata) }
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}
diff --git a/include/configs/smdk6400.h b/include/configs/smdk6400.h
new file mode 100644
index 0000000..b5deaa7
--- /dev/null
+++ b/include/configs/smdk6400.h
@@ -0,0 +1,304 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Gary Jennejohn <gj@denx.de>
+ * David Mueller <d.mueller@elsoft.ch>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * Configuation settings for the SAMSUNG SMDK6400(mDirac-III) 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
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_S3C6400		1	/* in a SAMSUNG S3C6400 SoC     */
+#define CONFIG_S3C64XX		1	/* in a SAMSUNG S3C64XX Family  */
+#define CONFIG_SMDK6400		1	/* on a SAMSUNG SMDK6400 Board  */
+
+#define CFG_SDRAM_BASE	0x50000000
+
+/* input clock of PLL: SMDK6400 has 12MHz input clock */
+#define CONFIG_SYS_CLK_FREQ	12000000
+
+#if !defined(CONFIG_NAND_SPL) && (TEXT_BASE >= 0xc0000000)
+#define CONFIG_ENABLE_MMU
+#endif
+
+#define CONFIG_MEMORY_UPPER_CODE
+
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+
+/*
+ * Architecture magic and machine type
+ */
+#define MACH_TYPE		1270
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+
+/*
+ * Size of malloc() pool
+ */
+#define CFG_MALLOC_LEN		(CFG_ENV_SIZE + 1024 * 1024)
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes for initial data */
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_DRIVER_CS8900	1	/* we have a CS8900 on-board	*/
+#define CS8900_BASE	  	0x18800300
+#define CS8900_BUS16		1 	/* follow the Linux driver	*/
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL1          1	/* we use SERIAL 1 on SMDK6400	*/
+
+#define CFG_HUSH_PARSER			/* use "hush" command parser	*/
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+#define CONFIG_CMDLINE_EDITING
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE		115200
+
+/***********************************************************
+ * Command definition
+ ***********************************************************/
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_NAND
+#if defined(CONFIG_BOOT_ONENAND)
+#define CONFIG_CMD_ONENAND
+#endif
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_ELF
+
+#define CONFIG_BOOTDELAY	3
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#if (CONFIG_COMMANDS & CONFIG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	115200	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	1	/* which serial port to use	 */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP				/* undef to save memory	      */
+#define CFG_PROMPT		"SMDK6400 # "	/* Monitor Command Prompt     */
+#define CFG_CBSIZE		256		/* Console I/O Buffer Size    */
+#define CFG_PBSIZE		384		/* Print Buffer Size          */
+#define CFG_MAXARGS		16		/* max number of command args */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size  */
+
+#define CFG_MEMTEST_START	CFG_SDRAM_BASE	/* memtest works on	      */
+#define CFG_MEMTEST_END		(CFG_SDRAM_BASE + 0x7e00000) /* 126MB in DRAM */
+
+#define CFG_LOAD_ADDR		CFG_SDRAM_BASE	/* default load address	*/
+
+#define CFG_HZ			1000
+
+/* valid baudrates */
+#define CFG_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	0x40000		/* regular stack 256KB */
+
+/**********************************
+ Support Clock Settings
+ **********************************
+ Setting	SYNC	ASYNC
+ ----------------------------------
+ 667_133_66	 X	  O
+ 533_133_66	 O	  O
+ 400_133_66	 X	  O
+ 400_100_50	 O	  O
+ **********************************/
+
+/*#define CONFIG_CLK_667_133_66*/
+#define CONFIG_CLK_533_133_66
+/*
+#define CONFIG_CLK_400_100_50
+#define CONFIG_CLK_400_133_66
+#define CONFIG_SYNC_MODE
+*/
+
+/* SMDK6400 has 2 banks of DRAM, but we use only one in U-Boot */
+#define CONFIG_NR_DRAM_BANKS	1
+#define PHYS_SDRAM_1		CFG_SDRAM_BASE	/* SDRAM Bank #1	*/
+#define PHYS_SDRAM_1_SIZE	0x08000000	/* 128 MB in Bank #1	*/
+
+#define CFG_FLASH_BASE		0x10000000
+#define CFG_MONITOR_BASE	0x00000000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks	*/
+/* AM29LV160B has 35 sectors, AM29LV800B - 19 */
+#define CFG_MAX_FLASH_SECT	40
+
+#define CONFIG_AMD_LV800
+#define CFG_FLASH_CFI		1	/* Use CFI parameters (needed?) */
+/* Use drivers/cfi_flash.c, even though the flash is not CFI-compliant	*/
+#define CFG_FLASH_CFI_DRIVER	1
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
+#define CONFIG_FLASH_CFI_LEGACY
+#define CFG_FLASH_LEGACY_512Kx16
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT	(5 * CFG_HZ) /* Timeout for Flash Erase	*/
+#define CFG_FLASH_WRITE_TOUT	(5 * CFG_HZ) /* Timeout for Flash Write	*/
+
+#define CFG_ENV_SIZE		0x4000	/* Total Size of Environment Sector */
+
+/*
+ * SMDK6400 board specific data
+ */
+
+#define CONFIG_IDENT_STRING	" for SMDK6400"
+
+/* base address for uboot */
+#define CFG_PHY_UBOOT_BASE	(CFG_SDRAM_BASE + 0x07e00000)
+/* total memory available to uboot */
+#define CFG_UBOOT_SIZE		(1024 * 1024)
+
+#ifdef CONFIG_ENABLE_MMU
+#define CFG_MAPPED_RAM_BASE	0xc0000000
+#define CONFIG_BOOTCOMMAND	"nand read 0xc0018000 0x60000 0x1c0000;" \
+				"bootm 0xc0018000"
+#else
+#define CFG_MAPPED_RAM_BASE	CFG_SDRAM_BASE
+#define CONFIG_BOOTCOMMAND	"nand read 0x50018000 0x60000 0x1c0000;" \
+				"bootm 0x50018000"
+#endif
+
+/* NAND U-Boot load and start address */
+#define CFG_UBOOT_BASE		(CFG_MAPPED_RAM_BASE + 0x07e00000)
+
+#define CFG_ENV_OFFSET		0x0040000
+
+/* NAND configuration */
+#define CFG_MAX_NAND_DEVICE	1
+#define CFG_NAND_BASE		0x70200010
+#define NAND_MAX_CHIPS		1
+#define CFG_S3C_NAND_HWECC
+
+#define CFG_NAND_SKIP_BAD_DOT_I	1  /* ".i" read skips bad blocks	      */
+#define CFG_NAND_WP		1
+#define CFG_NAND_YAFFS_WRITE	1  /* support yaffs write		      */
+#define CFG_NAND_BBT_2NDPAGE	1  /* bad-block markers in 1st and 2nd pages  */
+
+#define CFG_NAND_U_BOOT_DST	CFG_PHY_UBOOT_BASE	/* NUB load-addr      */
+#define CFG_NAND_U_BOOT_START	CFG_NAND_U_BOOT_DST	/* NUB start-addr     */
+
+#define CFG_NAND_U_BOOT_OFFS	(4 * 1024)	/* Offset to RAM U-Boot image */
+#define CFG_NAND_U_BOOT_SIZE	(252 * 1024)	/* Size of RAM U-Boot image   */
+
+/* NAND chip page size		*/
+#define CFG_NAND_PAGE_SIZE	2048
+/* NAND chip block size		*/
+#define CFG_NAND_BLOCK_SIZE	(128 * 1024)
+/* NAND chip page per block count  */
+#define CFG_NAND_PAGE_COUNT	64
+/* Location of the bad-block label */
+#define CFG_NAND_BAD_BLOCK_POS	0
+/* Extra address cycle for > 128MiB */
+#define CFG_NAND_5_ADDR_CYCLE
+
+/* Size of the block protected by one OOB (Spare Area in Samsung terminology) */
+#define CFG_NAND_ECCSIZE	2048 /* 512 */
+/* Number of ECC bytes per OOB */
+#define CFG_NAND_ECCBYTES	12 /* 3 */
+/* Number of ECC-blocks per NAND page */
+#define CFG_NAND_ECCSTEPS	(CFG_NAND_PAGE_SIZE / CFG_NAND_ECCSIZE)
+/* Size of a single OOB region */
+#define CFG_NAND_OOBSIZE	64 /* 16 */
+/* Number of ECC bytes per page */
+#define CFG_NAND_ECCTOTAL	(CFG_NAND_ECCBYTES * CFG_NAND_ECCSTEPS)
+/* ECC byte positions */
+#define CFG_NAND_ECCPOS		{8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}
+
+/* Boot configuration (define only one of next 3) */
+#define CONFIG_BOOT_NAND
+/* None of these are currently implemented. Left from the original Samsung
+ * version for reference
+#define CONFIG_BOOT_NOR
+#define CONFIG_BOOT_MOVINAND
+#define CONFIG_BOOT_ONENAND
+*/
+
+#define CONFIG_NAND
+#define CONFIG_NAND_S3C64XX
+/* Unimplemented or unsupported. See comment above.
+#define CONFIG_ONENAND
+#define CONFIG_MOVINAND
+*/
+
+/* Settings as above boot configuration */
+#define CFG_ENV_IS_IN_NAND
+#define CONFIG_BOOTARGS		"console=ttySAC,115200"
+#define CONFIG_EXTRA_ENV_SETTINGS "bootargs=" CONFIG_BOOTARGS
+
+#if !defined(CONFIG_ENABLE_MMU)
+#define CONFIG_CMD_USB			1
+#define CONFIG_USB_OHCI_NEW		1
+#define CFG_USB_OHCI_REGS_BASE		0x74300000
+#define CFG_USB_OHCI_SLOT_NAME		"s3c6400"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	3
+#define CFG_USB_OHCI_CPU_INIT		1
+#define LITTLEENDIAN			1	/* used by usb_ohci.c	*/
+
+#define CONFIG_USB_STORAGE	1
+#endif
+#define CONFIG_DOS_PARTITION	1
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_ENABLE_MMU)
+# error "usb_ohci.c is currently broken with MMU enabled."
+#endif
+
+#endif	/* __CONFIG_H */
diff --git a/nand_spl/board/samsung/smdk6400/Makefile b/nand_spl/board/samsung/smdk6400/Makefile
new file mode 100644
index 0000000..ae9eb2a
--- /dev/null
+++ b/nand_spl/board/samsung/smdk6400/Makefile
@@ -0,0 +1,106 @@
+#
+# (C) Copyright 2006-2007
+# Stefan Roese, DENX Software Engineering, sr at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+#
+
+CONFIG_NAND_SPL	= y
+
+include $(TOPDIR)/config.mk
+include $(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk
+
+LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds
+LDFLAGS	= -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
+AFLAGS	+= -DCONFIG_NAND_SPL
+CFLAGS	+= -DCONFIG_NAND_SPL
+
+SOBJS	= start.o cpu_init.o lowlevel_init.o
+COBJS	= nand_boot.o nand_ecc.o s3c64xx.o
+
+SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+__OBJS	:= $(SOBJS) $(COBJS)
+LNDIR	:= $(OBJTREE)/nand_spl/board/$(BOARDDIR)
+
+nandobj	:= $(OBJTREE)/nand_spl/
+
+ALL	= $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin
+
+all:	$(obj).depend $(ALL)
+
+$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl
+	$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@
+
+$(nandobj)u-boot-spl.bin:	$(nandobj)u-boot-spl
+	$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+
+$(nandobj)u-boot-spl:	$(OBJS)
+	cd $(LNDIR) && $(LD) $(LDFLAGS) $(__OBJS) \
+		-Map $(nandobj)u-boot-spl.map \
+		-o $(nandobj)u-boot-spl
+
+# create symbolic links for common files
+
+# from cpu directory
+$(obj)start.S:
+	@rm -f $@
+	@ln -s $(TOPDIR)/cpu/arm1176/start.S $@
+
+# from SoC directory
+$(obj)cpu_init.S:
+	@rm -f $@
+	@ln -s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@
+
+# from board directory
+$(obj)lowlevel_init.S:
+	@rm -f $@
+	@ln -s $(TOPDIR)/board/samsung/smdk6400/lowlevel_init.S $@
+
+# from nand_spl directory
+$(obj)nand_boot.c:
+	@rm -f $@
+	@ln -s $(TOPDIR)/nand_spl/nand_boot.c $@
+
+# from drivers/mtd/nand directory
+$(obj)nand_ecc.c:
+	@rm -f $@
+	@ln -s $(TOPDIR)/drivers/mtd/nand/nand_ecc.c $@
+
+$(obj)s3c64xx.c:
+	@rm -f $@
+	@ln -s $(TOPDIR)/drivers/mtd/nand/s3c64xx.c $@
+
+#########################################################################
+
+$(obj)%.o:	$(obj)%.S
+	$(CC) $(AFLAGS) -c -o $@ $<
+
+$(obj)%.o:	$(obj)%.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/nand_spl/board/samsung/smdk6400/config.mk b/nand_spl/board/samsung/smdk6400/config.mk
new file mode 100644
index 0000000..4b16230
--- /dev/null
+++ b/nand_spl/board/samsung/smdk6400/config.mk
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2006
+# Stefan Roese, DENX Software Engineering, sr 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
+#
+#
+# Samsung S3C64xx Reference Platform (smdk6400) board
+
+# TEXT_BASE for SPL:
+#
+# On S3C64xx platforms the SPL is located in SRAM@0.
+#
+# TEXT_BASE = 0
+
+include $(TOPDIR)/board/$(BOARDDIR)/config.mk
+
+# PAD_TO used to generate a 4kByte binary needed for the combined image
+# -> PAD_TO = TEXT_BASE + 4096
+PAD_TO	:= $(shell expr $$[$(TEXT_BASE) + 4096])
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
diff --git a/nand_spl/board/samsung/smdk6400/u-boot.lds b/nand_spl/board/samsung/smdk6400/u-boot.lds
new file mode 100644
index 0000000..1bf022c
--- /dev/null
+++ b/nand_spl/board/samsung/smdk6400/u-boot.lds
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  start.o	(.text)
+	  cpu_init.o	(.text)
+	  nand_boot.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 : { *(.bss) }
+	_end = .;
+}
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
                           ` (6 preceding siblings ...)
  2008-08-04 10:43         ` [U-Boot-Users] [PATCH 7/7 v2] ARM: Add support for S3C6400 based SMDK6400 board Guennadi Liakhovetski
@ 2008-08-04 11:00         ` Wolfgang Denk
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
  8 siblings, 0 replies; 36+ messages in thread
From: Wolfgang Denk @ 2008-08-04 11:00 UTC (permalink / raw)
  To: u-boot

In message <Pine.LNX.4.64.0808041206030.4715@axis700.grange> you wrote:
> 
> Sorry, looks like a matter of taste to me. There are also very few lines 
> over 80 characters left, but fixing them would look too awkward...

This is not a matter of taste. Please fix these, too!

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
It is the quality rather than the quantity that matters.
- Lucius Annaeus Seneca (4 B.C. - A.D. 65)

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 0/7 v3] SMDK6400 support
  2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
                           ` (7 preceding siblings ...)
  2008-08-04 11:00         ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Wolfgang Denk
@ 2008-08-04 12:44         ` Guennadi Liakhovetski
  2008-08-04 12:44           ` [U-Boot-Users] [PATCH 1/7 v3] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
                             ` (6 more replies)
  8 siblings, 7 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:44 UTC (permalink / raw)
  To: u-boot

Version 3: now all lines over 80 characters are gone.  And a couple more 
checkpatch warnings with them.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 1/7 v3] Add definition for the AM29LV800BB AMD NOR-flash
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
@ 2008-08-04 12:44           ` Guennadi Liakhovetski
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead Guennadi Liakhovetski
                             ` (5 subsequent siblings)
  6 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:44 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 drivers/mtd/jedec_flash.c |   17 +++++++++++++++++
 1 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/drivers/mtd/jedec_flash.c b/drivers/mtd/jedec_flash.c
index 9845e93..020647a 100644
--- a/drivers/mtd/jedec_flash.c
+++ b/drivers/mtd/jedec_flash.c
@@ -234,6 +234,23 @@ static const struct amd_flash_info jedec_table[] = {
 			ERASEINFO(0x10000,7),
 		}
 	},
+	{
+		.mfr_id		= MANUFACTURER_AMD,
+		.dev_id		= AM29LV800BB,
+		.name		= "AMD AM29LV800BB",
+		.uaddr		= {
+			[1] = MTD_UADDR_0x0555_0x02AA /* x16 */
+		},
+		.DevSize	= SIZE_1MiB,
+		.CmdSet		= CFI_CMDSET_AMD_LEGACY,
+		.NumEraseRegions= 4,
+		.regions	= {
+			ERASEINFO(0x04000, 1),
+			ERASEINFO(0x02000, 2),
+			ERASEINFO(0x08000, 1),
+			ERASEINFO(0x10000, 15),
+		}
+	},
 #endif
 };
 
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
  2008-08-04 12:44           ` [U-Boot-Users] [PATCH 1/7 v3] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
@ 2008-08-04 12:45           ` Guennadi Liakhovetski
  2008-08-04 22:28             ` Scott Wood
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 3/7 v3] ARM: Add arm1176 core with s3c6400 SoC Guennadi Liakhovetski
                             ` (4 subsequent siblings)
  6 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:45 UTC (permalink / raw)
  To: u-boot

I _think_ this should work with all NAND chips. Otherwise we might have to 
introduce a configuration variable.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 nand_spl/nand_boot.c |   64 ++++++++++++++++++++++++++-----------------------
 1 files changed, 34 insertions(+), 30 deletions(-)

diff --git a/nand_spl/nand_boot.c b/nand_spl/nand_boot.c
index 563a80b..0de4c4b 100644
--- a/nand_spl/nand_boot.c
+++ b/nand_spl/nand_boot.c
@@ -128,21 +128,6 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8
 }
 #endif
 
-static int nand_is_bad_block(struct mtd_info *mtd, int block)
-{
-	struct nand_chip *this = mtd->priv;
-
-	nand_command(mtd, block, 0, CFG_NAND_BAD_BLOCK_POS, NAND_CMD_READOOB);
-
-	/*
-	 * Read one byte
-	 */
-	if (this->read_byte(mtd) != 0xff)
-		return 1;
-
-	return 0;
-}
-
 static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 {
 	struct nand_chip *this = mtd->priv;
@@ -150,8 +135,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 	u_char *ecc_code;
 	u_char *oob_data;
 	int i;
-	int eccsize = CFG_NAND_ECCSIZE;
-	int eccbytes = CFG_NAND_ECCBYTES;
 	int eccsteps = CFG_NAND_ECCSTEPS;
 	uint8_t *p = dst;
 	int stat;
@@ -163,11 +146,12 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 	 */
 	ecc_calc = (u_char *)(CFG_SDRAM_BASE + 0x10000);
 	ecc_code = ecc_calc + 0x100;
-	oob_data = ecc_calc + 0x200;
+	oob_data = p + CFG_NAND_PAGE_SIZE; /* Append OOB to the page data */
 
-	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+	for (i = 0; eccsteps;
+	     eccsteps--, i += CFG_NAND_ECCBYTES, p += CFG_NAND_ECCSIZE) {
 		this->enable_hwecc(mtd, NAND_ECC_READ);
-		this->read_buf(mtd, p, eccsize);
+		this->read_buf(mtd, p, CFG_NAND_ECCSIZE);
 		this->calculate_ecc(mtd, p, &ecc_calc[i]);
 	}
 	this->read_buf(mtd, oob_data, CFG_NAND_OOBSIZE);
@@ -179,7 +163,8 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
 	eccsteps = CFG_NAND_ECCSTEPS;
 	p = dst;
 
-	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+	for (i = 0; eccsteps;
+	     eccsteps--, i += CFG_NAND_ECCBYTES, p += CFG_NAND_ECCSIZE) {
 		/* No chance to do something with the possible error message
 		 * from correct_data(). We just hope that all possible errors
 		 * are corrected by this routine.
@@ -195,6 +180,7 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst)
 	int block;
 	int blockcopy_count;
 	int page;
+	unsigned read = 0;
 
 	/*
 	 * offs has to be aligned to a block address!
@@ -202,18 +188,30 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst)
 	block = offs / CFG_NAND_BLOCK_SIZE;
 	blockcopy_count = 0;
 
-	while (blockcopy_count < (uboot_size / CFG_NAND_BLOCK_SIZE)) {
-		if (!nand_is_bad_block(mtd, block)) {
-			/*
-			 * Skip bad blocks
-			 */
-			for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) {
-				nand_read_page(mtd, block, page, dst);
-				dst += CFG_NAND_PAGE_SIZE;
+	while (blockcopy_count < ((uboot_size + CFG_NAND_BLOCK_SIZE - 1) /
+				  CFG_NAND_BLOCK_SIZE)) {
+		/*
+		 * Skip bad blocks
+		 */
+		int badblock = 0;
+		for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) {
+			nand_read_page(mtd, block, page, dst);
+			if ((!page
+#ifdef CFG_NAND_BBT_2NDPAGE
+			     || page == 1
+#endif
+				    ) && dst[CFG_NAND_PAGE_SIZE] != 0xff) {
+				badblock = 1;
+				break;
 			}
+			/* Overwrite skipped pages */
+			if (read >= offs)
+				dst += CFG_NAND_PAGE_SIZE;
+			read += CFG_NAND_PAGE_SIZE;
+		}
 
+		if (!badblock)
 			blockcopy_count++;
-		}
 
 		block++;
 	}
@@ -241,12 +239,18 @@ void nand_boot(void)
 	nand_chip.dev_ready = NULL;	/* preset to NULL */
 	board_nand_init(&nand_chip);
 
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&nand_info, 0);
+
 	/*
 	 * Load U-Boot image from NAND into RAM
 	 */
 	ret = nand_load(&nand_info, CFG_NAND_U_BOOT_OFFS, CFG_NAND_U_BOOT_SIZE,
 			(uchar *)CFG_NAND_U_BOOT_DST);
 
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&nand_info, -1);
+
 	/*
 	 * Jump to U-Boot image
 	 */
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 3/7 v3] ARM: Add arm1176 core with s3c6400 SoC
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
  2008-08-04 12:44           ` [U-Boot-Users] [PATCH 1/7 v3] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead Guennadi Liakhovetski
@ 2008-08-04 12:45           ` Guennadi Liakhovetski
  2008-08-04 20:06             ` [U-Boot-Users] [PATCH 3/7 v4] " Guennadi Liakhovetski
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 4/7 v3] USB: Add support for OHCI controller on s3c6400 Guennadi Liakhovetski
                             ` (3 subsequent siblings)
  6 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:45 UTC (permalink / raw)
  To: u-boot

This is a port of s3c6400 sources by Samsung from u-boot-1.1.6.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 cpu/arm1176/Makefile                    |   50 ++
 cpu/arm1176/config.mk                   |   35 ++
 cpu/arm1176/cpu.c                       |  189 +++++++
 cpu/arm1176/s3c64xx/Makefile            |   48 ++
 cpu/arm1176/s3c64xx/config.mk           |   34 ++
 cpu/arm1176/s3c64xx/cpu_init.S          |  142 +++++
 cpu/arm1176/s3c64xx/interrupts.c        |  280 ++++++++++
 cpu/arm1176/s3c64xx/speed.c             |  140 +++++
 cpu/arm1176/start.S                     |  469 ++++++++++++++++
 include/asm-arm/arch-s3c64xx/hardware.h |   63 +++
 include/common.h                        |    3 +-
 include/s3c6400.h                       |  884 +++++++++++++++++++++++++++++++
 include/s3c64x0.h                       |   92 ++++
 13 files changed, 2428 insertions(+), 1 deletions(-)
 create mode 100644 cpu/arm1176/Makefile
 create mode 100644 cpu/arm1176/config.mk
 create mode 100644 cpu/arm1176/cpu.c
 create mode 100644 cpu/arm1176/s3c64xx/Makefile
 create mode 100644 cpu/arm1176/s3c64xx/config.mk
 create mode 100644 cpu/arm1176/s3c64xx/cpu_init.S
 create mode 100644 cpu/arm1176/s3c64xx/interrupts.c
 create mode 100644 cpu/arm1176/s3c64xx/speed.c
 create mode 100644 cpu/arm1176/start.S
 create mode 100644 include/asm-arm/arch-s3c64xx/hardware.h
 create mode 100644 include/s3c6400.h
 create mode 100644 include/s3c64x0.h

diff --git a/cpu/arm1176/Makefile b/cpu/arm1176/Makefile
new file mode 100644
index 0000000..1ca9199
--- /dev/null
+++ b/cpu/arm1176/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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$(CPU).a
+
+START	= start.o
+COBJS	= cpu.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk
new file mode 100644
index 0000000..5083594
--- /dev/null
+++ b/cpu/arm1176/config.mk
@@ -0,0 +1,35 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@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
+#
+PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
+	-msoft-float
+
+# Make ARMv5 to allow more compilers to work, even though its v6.
+PLATFORM_CPPFLAGS += -march=armv5t
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c
new file mode 100644
index 0000000..a0a9268
--- /dev/null
+++ b/cpu/arm1176/cpu.c
@@ -0,0 +1,189 @@
+/*
+ * (C) Copyright 2004 Texas Insturments
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <s3c6400.h>
+
+static void cache_flush (void);
+
+/* read co-processor 15, register #1 (control register) */
+static unsigned long read_p15_c1 (void)
+{
+	unsigned long value;
+
+	__asm__ __volatile__(
+		"mrc	p15, 0, %0, c1, c0, 0   @ read control reg\n"
+		: "=r" (value)
+		:
+		: "memory");
+	return value;
+}
+
+/* write to co-processor 15, register #1 (control register) */
+static void write_p15_c1 (unsigned long value)
+{
+	__asm__ __volatile__(
+		"mcr	p15, 0, %0, c1, c0, 0   @ write it back\n"
+		:
+		: "r" (value)
+		: "memory");
+
+	read_p15_c1();
+}
+
+static void cp_delay (void)
+{
+	volatile int i;
+
+	/* Many OMAP regs need at least 2 nops  */
+	for (i = 0; i < 100; i++)
+		__asm__ __volatile__("nop\n");
+}
+
+/* See also ARM Ref. Man. */
+#define C1_MMU		(1 << 0)	/* mmu off/on */
+#define C1_ALIGN	(1 << 1)	/* alignment faults off/on */
+#define C1_DC		(1 << 2)	/* dcache off/on */
+#define C1_WB		(1 << 3)	/* merging write buffer on/off */
+#define C1_BIG_ENDIAN	(1 << 7)	/* big endian off/on */
+#define C1_SYS_PROT	(1 << 8)	/* system protection */
+#define C1_ROM_PROT	(1 << 9)	/* ROM protection */
+#define C1_IC		(1 << 12)	/* icache off/on */
+#define C1_HIGH_VECTORS	(1 << 13)	/* location of vectors: low/high */
+#define RESERVED_1	(0xf << 3)	/* must be 111b for R/W */
+
+int cpu_init (void)
+{
+	return 0;
+}
+
+int cleanup_before_linux (void)
+{
+	/*
+	 * this function is called just before we call linux
+	 * it prepares the processor for linux
+	 *
+	 * we turn off caches etc ...
+	 */
+
+	disable_interrupts ();
+
+	/* turn off I/D-cache */
+	icache_disable();
+	dcache_disable();
+	cache_flush();
+
+	return 0;
+}
+
+
+/* * reset the cpu by setting up the watchdog timer and let him time out */
+void reset_cpu (ulong ignored)
+{
+	printf("reset... \n\n\n");
+	SW_RST_REG = 0x6400;
+	/* loop forever and wait for reset to happen */
+	while (1) {
+		if (serial_tstc()) {
+			serial_getc();
+			break;
+		}
+	}
+	/*NOTREACHED*/
+}
+
+int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	disable_interrupts ();
+	reset_cpu (0);
+	/*NOTREACHED*/
+	return 0;
+}
+
+void icache_enable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();	/* get control reg. */
+	cp_delay ();
+	write_p15_c1 (reg | C1_IC);
+}
+
+void icache_disable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	write_p15_c1 (reg & ~C1_IC);
+}
+
+int icache_status (void)
+{
+	return (read_p15_c1 () & C1_IC) != 0;
+}
+
+/* It makes no sense to use the dcache if the MMU is not enabled */
+void dcache_enable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	write_p15_c1 (reg | C1_DC);
+}
+
+void dcache_disable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	reg &= ~C1_DC;
+	write_p15_c1 (reg);
+}
+
+int dcache_status (void)
+{
+	return (read_p15_c1 () & C1_DC) != 0;
+}
+
+/* flush I/D-cache */
+static void cache_flush (void)
+{
+	/* invalidate both caches and flush btb */
+	asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0));
+	/* mem barrier to sync things */
+	asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0));
+}
diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile
new file mode 100644
index 0000000..fa4ee3f
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/Makefile
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS-y	= interrupts.o
+COBJS-$(CONFIG_S3C6400)	+= cpu_init.o speed.o
+
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk
new file mode 100644
index 0000000..204e880
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@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
+#
+PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
+	-msoft-float
+
+# Make ARMv5 to allow more compilers to work, even though its v6.
+PLATFORM_CPPFLAGS += -march=armv5t
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/s3c64xx/cpu_init.S b/cpu/arm1176/s3c64xx/cpu_init.S
new file mode 100644
index 0000000..08bda99
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/cpu_init.S
@@ -0,0 +1,142 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <config.h>
+#include <s3c6400.h>
+
+	.globl mem_ctrl_asm_init
+mem_ctrl_asm_init:
+	/* Memory subsystem address 0x7e00f120 */
+	ldr	r0, =ELFIN_MEM_SYS_CFG
+
+	/* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
+	mov	r1, #0xd
+	str	r1, [r0]
+
+	/* DMC1 base address 0x7e001000 */
+	ldr	r0, =ELFIN_DMC1_BASE
+
+	ldr	r1, =0x4
+	str	r1, [r0, #INDEX_DMC_MEMC_CMD]
+
+	ldr	r1, =DMC_DDR_REFRESH_PRD
+	str	r1, [r0, #INDEX_DMC_REFRESH_PRD]
+
+	ldr	r1, =DMC_DDR_CAS_LATENCY
+	str	r1, [r0, #INDEX_DMC_CAS_LATENCY]
+
+	ldr	r1, =DMC_DDR_t_DQSS
+	str	r1, [r0, #INDEX_DMC_T_DQSS]
+
+	ldr	r1, =DMC_DDR_t_MRD
+	str	r1, [r0, #INDEX_DMC_T_MRD]
+
+	ldr	r1, =DMC_DDR_t_RAS
+	str	r1, [r0, #INDEX_DMC_T_RAS]
+
+	ldr	r1, =DMC_DDR_t_RC
+	str	r1, [r0, #INDEX_DMC_T_RC]
+
+	ldr	r1, =DMC_DDR_t_RCD
+	ldr	r2, =DMC_DDR_schedule_RCD
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RCD]
+
+	ldr	r1, =DMC_DDR_t_RFC
+	ldr	r2, =DMC_DDR_schedule_RFC
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RFC]
+
+	ldr	r1, =DMC_DDR_t_RP
+	ldr	r2, =DMC_DDR_schedule_RP
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RP]
+
+	ldr	r1, =DMC_DDR_t_RRD
+	str	r1, [r0, #INDEX_DMC_T_RRD]
+
+	ldr	r1, =DMC_DDR_t_WR
+	str	r1, [r0, #INDEX_DMC_T_WR]
+
+	ldr	r1, =DMC_DDR_t_WTR
+	str	r1, [r0, #INDEX_DMC_T_WTR]
+
+	ldr	r1, =DMC_DDR_t_XP
+	str	r1, [r0, #INDEX_DMC_T_XP]
+
+	ldr	r1, =DMC_DDR_t_XSR
+	str	r1, [r0, #INDEX_DMC_T_XSR]
+
+	ldr	r1, =DMC_DDR_t_ESR
+	str	r1, [r0, #INDEX_DMC_T_ESR]
+
+	ldr	r1, =DMC1_MEM_CFG
+	str	r1, [r0, #INDEX_DMC_MEMORY_CFG]
+
+	ldr	r1, =DMC1_MEM_CFG2
+	str	r1, [r0, #INDEX_DMC_MEMORY_CFG2]
+
+	ldr	r1, =DMC1_CHIP0_CFG
+	str	r1, [r0, #INDEX_DMC_CHIP_0_CFG]
+
+	ldr	r1, =DMC_DDR_32_CFG
+	str	r1, [r0, #INDEX_DMC_USER_CONFIG]
+
+	/* DMC0 DDR Chip 0 configuration direct command reg */
+	ldr	r1, =DMC_NOP0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Precharge All */
+	ldr	r1, =DMC_PA0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Auto Refresh 2 time */
+	ldr	r1, =DMC_AR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* MRS */
+	ldr	r1, =DMC_mDDR_EMR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Mode Reg */
+	ldr	r1, =DMC_mDDR_MR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Enable DMC1 */
+	mov	r1, #0x0
+	str	r1, [r0, #INDEX_DMC_MEMC_CMD]
+
+check_dmc1_ready:
+	ldr	r1, [r0, #INDEX_DMC_MEMC_STATUS]
+	mov	r2, #0x3
+	and	r1, r1, r2
+	cmp	r1, #0x1
+	bne	check_dmc1_ready
+	nop
+
+	mov	pc, lr
+
+	.ltorg
diff --git a/cpu/arm1176/s3c64xx/interrupts.c b/cpu/arm1176/s3c64xx/interrupts.c
new file mode 100644
index 0000000..4233e8c
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/interrupts.c
@@ -0,0 +1,280 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
+#include <asm/proc-armv/ptrace.h>
+#include <s3c6400.h>
+
+static ulong timer_load_val;
+
+#define PRESCALER	167
+
+static s3c64xx_timers *s3c64xx_get_base_timers(void)
+{
+	return (s3c64xx_timers *)ELFIN_TIMER_BASE;
+}
+
+/* macro to read the 16 bit timer */
+static inline ulong read_timer(void)
+{
+	s3c64xx_timers *const timers = s3c64xx_get_base_timers();
+
+	return timers->TCNTO4;
+}
+
+/* Internal tick units */
+/* Last decremneter snapshot */
+static unsigned long lastdec;
+/* Monotonic incrementing timer */
+static unsigned long long timestamp;
+
+void enable_interrupts(void)
+{
+	return;
+}
+int disable_interrupts(void)
+{
+	return 0;
+}
+
+void bad_mode(void)
+{
+	panic("Resetting CPU ...\n");
+	reset_cpu(0);
+}
+
+void show_regs(struct pt_regs *regs)
+{
+	unsigned long flags;
+	const char *processor_modes[] = {
+		"USER_26", "FIQ_26", "IRQ_26", "SVC_26",
+		"UK4_26", "UK5_26", "UK6_26", "UK7_26",
+		"UK8_26", "UK9_26", "UK10_26", "UK11_26",
+		"UK12_26", "UK13_26", "UK14_26", "UK15_26",
+		"USER_32", "FIQ_32", "IRQ_32", "SVC_32",
+		"UK4_32", "UK5_32", "UK6_32", "ABT_32",
+		"UK8_32", "UK9_32", "UK10_32", "UND_32",
+		"UK12_32", "UK13_32", "UK14_32", "SYS_32",
+	};
+
+	flags = condition_codes(regs);
+
+	printf("pc : [<%08lx>]	   lr : [<%08lx>]\n"
+	       "sp : %08lx  ip : %08lx	 fp : %08lx\n",
+	       instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp,
+	       regs->ARM_ip, regs->ARM_fp);
+	printf("r10: %08lx  r9 : %08lx	 r8 : %08lx\n", regs->ARM_r10,
+	       regs->ARM_r9, regs->ARM_r8);
+	printf("r7 : %08lx  r6 : %08lx	 r5 : %08lx  r4 : %08lx\n",
+	       regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+	printf("r3 : %08lx  r2 : %08lx	 r1 : %08lx  r0 : %08lx\n",
+	       regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+	printf("Flags: %c%c%c%c",
+	       flags & CC_N_BIT ? 'N' : 'n',
+	       flags & CC_Z_BIT ? 'Z' : 'z',
+	       flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+	printf("  IRQs %s  FIQs %s  Mode %s%s\n",
+	       interrupts_enabled(regs) ? "on" : "off",
+	       fast_interrupts_enabled(regs) ? "on" : "off",
+	       processor_modes[processor_mode(regs)], thumb_mode(regs) ?
+	       " (T)" : "");
+}
+
+void do_undefined_instruction(struct pt_regs *pt_regs)
+{
+	printf("undefined instruction\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_software_interrupt(struct pt_regs *pt_regs)
+{
+	printf("software interrupt\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_prefetch_abort(struct pt_regs *pt_regs)
+{
+	printf("prefetch abort\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_data_abort(struct pt_regs *pt_regs)
+{
+	printf("data abort\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_not_used(struct pt_regs *pt_regs)
+{
+	printf("not used\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_fiq(struct pt_regs *pt_regs)
+{
+	printf("fast interrupt request\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_irq(struct pt_regs *pt_regs)
+{
+	printf("interrupt request\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+int interrupt_init(void)
+{
+	s3c64xx_timers *const timers = s3c64xx_get_base_timers();
+
+	/* use PWM Timer 4 because it has no output */
+	/*
+	 * We use the following scheme for the timer:
+	 * Prescaler is hard fixed at 167, divider at 1/4.
+	 * This gives at PCLK frequency 66MHz approx. 10us ticks
+	 * The timer is set to wrap after 100s, at 66MHz this obviously
+	 * happens after 10,000,000 ticks. A long variable can thus
+	 * keep values up to 40,000s, i.e., 11 hours. This should be
+	 * enough for most uses:-) Possible optimizations: select a
+	 * binary-friendly frequency, e.g., 1ms / 128. Also calculate
+	 * the prescaler automatically for other PCLK frequencies.
+	 */
+	/* Set timer frequency to 500KHz, at 66MHz we get prescaler=132 < 255 */
+	timers->TCFG0 = PRESCALER << 8;
+	if (timer_load_val == 0) {
+		/*
+		 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 and
+		 * prescaler = 16. Should be 10390 @33.25MHz and 15625 @ 50 MHz
+		 */
+		timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */
+		/*printf("Calculated %lu timer_load_val\n", timer_load_val);*/
+		timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000;
+	}
+
+	/* load value for 10 ms timeout */
+	lastdec = timers->TCNTB4 = timer_load_val;
+	/* auto load, manual update of Timer 4 */
+	timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO |
+		TCON_4_UPDATE;
+	/* auto load, start Timer 4 */
+	timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON;
+	timestamp = 0;
+
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	ulong now = read_timer();
+
+	if (lastdec >= now) {
+		/* normal mode */
+		timestamp += lastdec - now;
+	} else {
+		/* we have an overflow ... */
+		timestamp += lastdec + timer_load_val - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	/* We overrun in 100s */
+	return (ulong)(timer_load_val / 100);
+}
+
+void reset_timer_masked(void)
+{
+	/* reset time */
+	lastdec = read_timer();
+	timestamp = 0;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer_masked(void)
+{
+	return get_ticks() / (timer_load_val / (100 * CFG_HZ));
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t * (timer_load_val / (100 * CFG_HZ));
+}
+
+void udelay(unsigned long usec)
+{
+	unsigned long long tmp;
+	ulong tmo;
+
+	tmo = (usec + 9) / 10;
+	tmp = get_ticks() + tmo;	/* get current timestamp */
+
+	while (get_ticks() < tmp)/* loop till event */
+		 /*NOP*/;
+}
diff --git a/cpu/arm1176/s3c64xx/speed.c b/cpu/arm1176/s3c64xx/speed.c
new file mode 100644
index 0000000..bb54cb3
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/speed.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2001-2004
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * 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
+ */
+
+/*
+ * This code should work for both the S3C2400 and the S3C2410
+ * as they seem to have the same PLL and clock machinery inside.
+ * The different address mapping is handled by the s3c24xx.h files below.
+ */
+
+#include <common.h>
+#include <s3c6400.h>
+
+#define APLL 0
+#define MPLL 1
+#define EPLL 2
+
+/* ------------------------------------------------------------------------- */
+/*
+ * NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+static ulong get_PLLCLK(int pllreg)
+{
+	ulong r, m, p, s;
+
+	if (pllreg == APLL)
+		r = APLL_CON_REG;
+	else if (pllreg == MPLL)
+		r = MPLL_CON_REG;
+	else if (pllreg == EPLL)
+		r = EPLL_CON0_REG;
+	else
+		hang();
+
+	m = (r >> 16) & 0x3ff;
+	p = (r >> 8) & 0x3f;
+	s = r & 0x7;
+
+	return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s)));
+}
+
+/* return ARMCORE frequency */
+ulong get_ARMCLK(void)
+{
+	ulong div;
+
+	div = CLK_DIV0_REG;
+
+	return get_PLLCLK(APLL) / ((div & 0x7) + 1);
+}
+
+/* return FCLK frequency */
+ulong get_FCLK(void)
+{
+	return get_PLLCLK(APLL);
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+	ulong fclk;
+
+	uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
+	uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1;
+
+	/*
+	 * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on
+	 * s3c6400 and is always 0, and it is indeed running in ASYNC mode
+	 */
+	if (OTHERS_REG & 0x80)
+		fclk = get_FCLK();		/* SYNC Mode	*/
+	else
+		fclk = get_PLLCLK(MPLL);	/* ASYNC Mode	*/
+
+	return fclk / (hclk_div * hclkx2_div);
+}
+
+/* return PCLK frequency */
+ulong get_PCLK(void)
+{
+	ulong fclk;
+	uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
+	uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1;
+
+	if (OTHERS_REG & 0x80)
+		fclk = get_FCLK();		/* SYNC Mode	*/
+	else
+		fclk = get_PLLCLK(MPLL);	/* ASYNC Mode	*/
+
+	return fclk / (hclkx2_div * pre_div);
+}
+
+/* return UCLK frequency */
+ulong get_UCLK(void)
+{
+	return get_PLLCLK(EPLL);
+}
+
+int print_cpuinfo(void)
+{
+	printf("\nCPU:     S3C6400@%luMHz\n", get_ARMCLK() / 1000000);
+	printf("         Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ",
+	       get_FCLK() / 1000000, get_HCLK() / 1000000,
+	       get_PCLK() / 1000000);
+
+	if (OTHERS_REG & 0x80)
+		printf("(SYNC Mode) \n");
+	else
+		printf("(ASYNC Mode) \n");
+	return 0;
+}
diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S
new file mode 100644
index 0000000..00cc186
--- /dev/null
+++ b/cpu/arm1176/start.S
@@ -0,0 +1,469 @@
+/*
+ *  armboot - Startup Code for S3C6400/ARM1176 CPU-core
+ *
+ * Copyright (c) 2007	Samsung Electronics
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+ *
+ * 2007-09-21 - Restructured codes by jsgood (jsgood.yang at samsung.com)
+ * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
+ * jsgood (jsgood.yang at samsung.com)
+ * Base codes by scsuh (sc.suh)
+ */
+
+#include <config.h>
+#include <version.h>
+#ifdef CONFIG_ENABLE_MMU
+#include <asm/proc/domain.h>
+#endif
+#include <s3c6400.h>
+
+#if !defined(CONFIG_ENABLE_MMU) && !defined(CFG_PHY_UBOOT_BASE)
+#define CFG_PHY_UBOOT_BASE	CFG_UBOOT_BASE
+#endif
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table as in table 3.1 in [1]
+ *
+ *************************************************************************
+ */
+
+.globl _start
+_start: b	reset
+#ifndef CONFIG_NAND_SPL
+	ldr	pc, _undefined_instruction
+	ldr	pc, _software_interrupt
+	ldr	pc, _prefetch_abort
+	ldr	pc, _data_abort
+	ldr	pc, _not_used
+	ldr	pc, _irq
+	ldr	pc, _fiq
+
+_undefined_instruction:
+	.word undefined_instruction
+_software_interrupt:
+	.word software_interrupt
+_prefetch_abort:
+	.word prefetch_abort
+_data_abort:
+	.word data_abort
+_not_used:
+	.word not_used
+_irq:
+	.word irq
+_fiq:
+	.word fiq
+_pad:
+	.word 0x12345678 /* now 16*4=64 */
+#else
+	. = _start + 64
+#endif
+
+.global _end_vect
+_end_vect:
+	.balignl 16,0xdeadbeef
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+/*
+ * Below variable is very important because we use MMU in U-Boot.
+ * Without it, we cannot run code correctly before MMU is ON.
+ * by scsuh.
+ */
+_TEXT_PHY_BASE:
+	.word	CFG_PHY_UBOOT_BASE
+
+.globl _armboot_start
+_armboot_start:
+	.word _start
+
+/*
+ * These are defined in the board-specific linker script.
+ */
+.globl _bss_start
+_bss_start:
+	.word __bss_start
+
+.globl _bss_end
+_bss_end:
+	.word _end
+
+/*
+ * the actual reset code
+ */
+
+reset:
+	/*
+	 * set the cpu to SVC32 mode
+	 */
+	mrs	r0,cpsr
+	bic	r0,r0,#0x3f
+	orr	r0,r0,#0xd3
+	msr	cpsr,r0
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+	/*
+	 * we do sys-critical inits only at reboot,
+	 * not when booting from ram!
+	 */
+cpu_init_crit:
+	/*
+	 * When booting from NAND - it has definitely been a reset, so, no need
+	 * to flush caches and disable the MMU
+	 */
+#ifndef CONFIG_NAND_SPL
+	/*
+	 * flush v4 I/D caches
+	 */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
+	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
+
+	/*
+	 * disable MMU stuff and caches
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
+	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
+	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
+	/* Prepare to disable the MMU */
+	adr	r1, mmu_disable_phys
+	/* We presume we're within the first 1024 bytes */
+	and	r1, r1, #0x3fc
+	ldr	r2, _TEXT_PHY_BASE
+	ldr	r3, =0xfff00000
+	and	r2, r2, r3
+	orr	r2, r2, r1
+	b	mmu_disable
+
+	.align 5
+	/* Run in a single cache-line */
+mmu_disable:
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	mov	pc, r2
+#endif
+
+mmu_disable_phys:
+	/* Peri port setup */
+	ldr	r0, =0x70000000
+	orr	r0, r0, #0x13
+	mcr	p15,0,r0,c15,c2,4       @ 256M (0x70000000 - 0x7fffffff)
+
+	/*
+	 * Go setup Memory and board specific bits prior to relocation.
+	 */
+	bl	lowlevel_init		/* go setup pll,mux,memory */
+
+after_copy:
+#ifdef CONFIG_ENABLE_MMU
+enable_mmu:
+	/* enable domain access */
+	ldr	r5, =0x0000ffff
+	mcr	p15, 0, r5, c3, c0, 0	/* load domain access register */
+
+	/* Set the TTB register */
+	ldr	r0, _mmu_table_base
+	ldr	r1, =CFG_PHY_UBOOT_BASE
+	ldr	r2, =0xfff00000
+	bic	r0, r0, r2
+	orr	r1, r0, r1
+	mcr	p15, 0, r1, c2, c0, 0
+
+	/* Enable the MMU */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #1		/* Set CR_M to enable MMU */
+
+	/* Prepare to enable the MMU */
+	adr	r1, skip_hw_init
+	and	r1, r1, #0x3fc
+	ldr	r2, _TEXT_BASE
+	ldr	r3, =0xfff00000
+	and	r2, r2, r3
+	orr	r2, r2, r1
+	b	mmu_enable
+
+	.align 5
+	/* Run in a single cache-line */
+mmu_enable:
+
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	mov	pc, r2
+#endif
+
+skip_hw_init:
+	/* Set up the stack						    */
+stack_setup:
+#ifdef CONFIG_MEMORY_UPPER_CODE
+	ldr	sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
+#else
+	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
+	sub	r0, r0, #CFG_MALLOC_LEN	/* malloc area                      */
+	sub	r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
+	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
+
+#endif
+
+clear_bss:
+	ldr	r0, _bss_start		/* find start of bss segment        */
+	ldr	r1, _bss_end		/* stop here                        */
+	mov 	r2, #0			/* clear                            */
+
+clbss_l:
+	str	r2, [r0]		/* clear loop...                    */
+	add	r0, r0, #4
+	cmp	r0, r1
+	ble	clbss_l
+
+#ifndef CONFIG_NAND_SPL
+	ldr	pc, _start_armboot
+
+_start_armboot:
+	.word start_armboot
+#else
+	b	nand_boot
+/*	.word nand_boot*/
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+_mmu_table_base:
+	.word mmu_table
+#endif
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * we assume that cache operation is done before. (eg. cleanup_before_linux())
+ * actually, we don't need to do anything about cache if not use d-cache in
+ * U-Boot. So, in this function we clean only MMU. by scsuh
+ *
+ * void	theLastJump(void *kernel, int arch_num, uint boot_params);
+ */
+#ifdef CONFIG_ENABLE_MMU
+	.globl theLastJump
+theLastJump:
+	mov	r9, r0
+	ldr	r3, =0xfff00000
+	ldr	r4, _TEXT_PHY_BASE
+	adr	r5, phy_last_jump
+	bic	r5, r5, r3
+	orr	r5, r5, r4
+	mov	pc, r5
+phy_last_jump:
+	/*
+	 * disable MMU stuff
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	/* clear bits 13, 9:8 (--V- --RS) */
+	bic	r0, r0, #0x00000087	/* clear bits 7, 2:0 (B--- -CAM) */
+	orr	r0, r0, #0x00000002	/* set bit 2 (A) Align */
+	orr	r0, r0, #0x00001000	/* set bit 12 (I) I-Cache */
+	mcr	p15, 0, r0, c1, c0, 0
+
+	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
+
+	mov	r0, #0
+	mov	pc, r9
+#endif
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+@
+@ IRQ stack frame.
+@
+#define S_FRAME_SIZE	72
+
+#define S_OLD_R0	68
+#define S_PSR		64
+#define S_PC		60
+#define S_LR		56
+#define S_SP		52
+
+#define S_IP		48
+#define S_FP		44
+#define S_R10		40
+#define S_R9		36
+#define S_R8		32
+#define S_R7		28
+#define S_R6		24
+#define S_R5		20
+#define S_R4		16
+#define S_R3		12
+#define S_R2		8
+#define S_R1		4
+#define S_R0		0
+
+#define MODE_SVC 0x13
+#define I_BIT	 0x80
+
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ */
+
+	.macro	bad_save_user_regs
+	/* carve out a frame on current user stack */
+	sub	sp, sp, #S_FRAME_SIZE
+	/* Save user registers (now in svc mode) r0-r12 */
+	stmia	sp, {r0 - r12}
+
+	ldr	r2, _armboot_start
+	sub	r2, r2, #(CFG_MALLOC_LEN)
+	/* set base 2 words into abort stack */
+	sub	r2, r2, #(CFG_GBL_DATA_SIZE+8)
+	/* get values for "aborted" pc and cpsr (into parm regs) */
+	ldmia	r2, {r2 - r3}
+	/* grab pointer to old stack */
+	add	r0, sp, #S_FRAME_SIZE
+
+	add	r5, sp, #S_SP
+	mov	r1, lr
+	/* save sp_SVC, lr_SVC, pc, cpsr */
+	stmia	r5, {r0 - r3}
+	/* save current stack into r0 (param register) */
+	mov	r0, sp
+	.endm
+
+	.macro get_bad_stack
+	/* setup our mode stack (enter in banked mode) */
+	ldr	r13, _armboot_start
+	/* move past malloc pool */
+	sub	r13, r13, #(CFG_MALLOC_LEN)
+	/* move to reserved a couple spots for abort stack */
+	sub	r13, r13, #(CFG_GBL_DATA_SIZE + 8)
+
+	/* save caller lr in position 0 of saved stack */
+	str	lr, [r13]
+	/* get the spsr */
+	mrs	lr, spsr
+	/* save spsr in position 1 of saved stack */
+	str	lr, [r13, #4]
+
+	/* prepare SVC-Mode */
+	mov	r13, #MODE_SVC
+	@ msr	spsr_c, r13
+	/* switch modes, make sure moves will execute */
+	msr	spsr, r13
+	/* capture return pc */
+	mov	lr, pc
+	/* jump to next instruction & switch modes. */
+	movs	pc, lr
+	.endm
+
+	.macro get_bad_stack_swi
+	/* space on current stack for scratch reg. */
+	sub	r13, r13, #4
+	/* save R0's value. */
+	str	r0, [r13]
+	/* get data regions start */
+	ldr	r0, _armboot_start
+	/* move past malloc pool */
+	sub	r0, r0, #(CFG_MALLOC_LEN)
+	/* move past gbl and a couple spots for abort stack */
+	sub	r0, r0, #(CFG_GBL_DATA_SIZE + 8)
+	/* save caller lr in position 0 of saved stack */
+	str	lr, [r0]
+	/* get the spsr */
+	mrs	r0, spsr
+	/* save spsr in position 1 of saved stack */
+	str	lr, [r0, #4]
+	/* restore r0 */
+	ldr	r0, [r13]
+	/* pop stack entry */
+	add	r13, r13, #4
+	.endm
+
+/*
+ * exception handlers
+ */
+	.align	5
+undefined_instruction:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_undefined_instruction
+
+	.align	5
+software_interrupt:
+	get_bad_stack_swi
+	bad_save_user_regs
+	bl	do_software_interrupt
+
+	.align	5
+prefetch_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_prefetch_abort
+
+	.align	5
+data_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_data_abort
+
+	.align	5
+not_used:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_not_used
+
+	.align	5
+irq:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_irq
+
+	.align	5
+fiq:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_fiq
+#endif /* CONFIG_NAND_SPL */
diff --git a/include/asm-arm/arch-s3c64xx/hardware.h b/include/asm-arm/arch-s3c64xx/hardware.h
new file mode 100644
index 0000000..84d24c9
--- /dev/null
+++ b/include/asm-arm/arch-s3c64xx/hardware.h
@@ -0,0 +1,63 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 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 _ARCH_HARDWARE_H_
+#define _ARCH_HARDWARE_H_
+
+#include <asm/sizes.h>
+
+#ifndef __ASSEMBLY__
+#define UData(Data)	((unsigned long) (Data))
+
+#define __REG(x)	(*(vu_long *)(x))
+#define __REGl(x)	(*(vu_long *)(x))
+#define __REGw(x)	(*(vu_short *)(x))
+#define __REGb(x)	(*(vu_char *)(x))
+#define __REG2(x, y)	(*(vu_long *)((x) + (y)))
+#else
+#define UData(Data)	(Data)
+
+#define __REG(x)	(x)
+#define __REGl(x)	(x)
+#define __REGw(x)	(x)
+#define __REGb(x)	(x)
+#define __REG2(x, y)	((x) + (y))
+#endif
+
+#define Fld(Size, Shft)	(((Size) << 16) + (Shft))
+
+#define FSize(Field)	((Field) >> 16)
+#define FShft(Field)	((Field) & 0x0000FFFF)
+#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field)	(UData (1) << FShft (Field))
+
+#define FClrBit(Data, Bit)	(Data = (Data & ~(Bit)))
+#define FClrFld(Data, Field)	(Data = (Data & ~FMsk(Field)))
+
+#define FInsrt(Value, Field) \
+			(UData (Value) << FShft (Field))
+
+#define FExtr(Data, Field) \
+			((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+#endif /* _ARCH_HARDWARE_H_ */
diff --git a/include/common.h b/include/common.h
index 2fcb1fd..10d56e0 100644
--- a/include/common.h
+++ b/include/common.h
@@ -489,7 +489,8 @@ int	prt_mpc8220_clks (void);
 ulong	get_OPB_freq (void);
 ulong	get_PCI_freq (void);
 #endif
-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X)
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
+	defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400)
 void	s3c2410_irq(void);
 #define ARM920_IRQ_CALLBACK s3c2410_irq
 ulong	get_FCLK (void);
diff --git a/include/s3c6400.h b/include/s3c6400.h
new file mode 100644
index 0000000..5b97bad
--- /dev/null
+++ b/include/s3c6400.h
@@ -0,0 +1,884 @@
+/*
+ * (C) Copyright 2007
+ * Byungjae Lee, Samsung Erectronics, bjlee at samsung.com.
+ *      - only support for S3C6400
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 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	    : s3c6400.h
+ *
+ * Based on S3C6400 User's manual Rev 0.0
+ ************************************************/
+
+#ifndef __S3C6400_H__
+#define __S3C6400_H__
+
+#ifndef CONFIG_S3C6400
+#define CONFIG_S3C6400		1
+#endif
+
+#define S3C64XX_UART_CHANNELS	3
+#define S3C64XX_SPI_CHANNELS	2
+
+#include <asm/hardware.h>
+
+#define ELFIN_CLOCK_POWER_BASE	0x7e00f000
+
+/* Clock & Power Controller for mDirac3*/
+#define APLL_LOCK_OFFSET	0x00
+#define MPLL_LOCK_OFFSET	0x04
+#define EPLL_LOCK_OFFSET	0x08
+#define APLL_CON_OFFSET		0x0C
+#define MPLL_CON_OFFSET		0x10
+#define EPLL_CON0_OFFSET	0x14
+#define EPLL_CON1_OFFSET	0x18
+#define CLK_SRC_OFFSET		0x1C
+#define CLK_DIV0_OFFSET		0x20
+#define CLK_DIV1_OFFSET		0x24
+#define CLK_DIV2_OFFSET		0x28
+#define CLK_OUT_OFFSET		0x2C
+#define HCLK_GATE_OFFSET	0x30
+#define PCLK_GATE_OFFSET	0x34
+#define SCLK_GATE_OFFSET	0x38
+#define AHB_CON0_OFFSET		0x100
+#define AHB_CON1_OFFSET		0x104
+#define AHB_CON2_OFFSET		0x108
+#define SELECT_DMA_OFFSET	0x110
+#define SW_RST_OFFSET		0x114
+#define SYS_ID_OFFSET		0x118
+#define MEM_SYS_CFG_OFFSET	0x120
+#define QOS_OVERRIDE0_OFFSET	0x124
+#define QOS_OVERRIDE1_OFFSET	0x128
+#define MEM_CFG_STAT_OFFSET	0x12C
+#define PWR_CFG_OFFSET		0x804
+#define EINT_MASK_OFFSET	0x808
+#define NOR_CFG_OFFSET		0x810
+#define STOP_CFG_OFFSET		0x814
+#define SLEEP_CFG_OFFSET	0x818
+#define OSC_FREQ_OFFSET		0x820
+#define OSC_STABLE_OFFSET	0x824
+#define PWR_STABLE_OFFSET	0x828
+#define FPC_STABLE_OFFSET	0x82C
+#define MTC_STABLE_OFFSET	0x830
+#define OTHERS_OFFSET		0x900
+#define RST_STAT_OFFSET		0x904
+#define WAKEUP_STAT_OFFSET	0x908
+#define BLK_PWR_STAT_OFFSET	0x90C
+#define INF_REG0_OFFSET		0xA00
+#define INF_REG1_OFFSET		0xA04
+#define INF_REG2_OFFSET		0xA08
+#define INF_REG3_OFFSET		0xA0C
+#define INF_REG4_OFFSET		0xA10
+#define INF_REG5_OFFSET		0xA14
+#define INF_REG6_OFFSET		0xA18
+#define INF_REG7_OFFSET		0xA1C
+
+#define OSC_CNT_VAL_OFFSET	0x824
+#define PWR_CNT_VAL_OFFSET	0x828
+#define FPC_CNT_VAL_OFFSET	0x82C
+#define MTC_CNT_VAL_OFFSET	0x830
+
+#define APLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET)
+#define MPLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET)
+#define EPLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET)
+#define APLL_CON_REG		__REG(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET)
+#define MPLL_CON_REG		__REG(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET)
+#define EPLL_CON0_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET)
+#define EPLL_CON1_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET)
+#define CLK_SRC_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET)
+#define CLK_DIV0_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET)
+#define CLK_DIV1_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET)
+#define CLK_DIV2_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET)
+#define CLK_OUT_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET)
+#define HCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET)
+#define PCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET)
+#define SCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET)
+#define AHB_CON0_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET)
+#define AHB_CON1_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET)
+#define AHB_CON2_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET)
+#define SELECT_DMA_REG		__REG(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET)
+#define SW_RST_REG		__REG(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET)
+#define SYS_ID_REG		__REG(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET)
+#define MEM_SYS_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET)
+#define QOS_OVERRIDE0_REG	__REG(ELFIN_CLOCK_POWER_BASE+
+				      QOS_OVERRIDE0_OFFSET)
+#define QOS_OVERRIDE1_REG	__REG(ELFIN_CLOCK_POWER_BASE+
+				      QOS_OVERRIDE1_OFFSET)
+#define MEM_CFG_STAT_REG	__REG(ELFIN_CLOCK_POWER_BASE+
+				      MEM_CFG_STAT_OFFSET)
+#define PWR_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET)
+#define EINT_MASK_REG		__REG(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET)
+#define NOR_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET)
+#define STOP_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET)
+#define SLEEP_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET)
+#define OSC_FREQ_REG		__REG(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET)
+#define OSC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET)
+#define PWR_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET)
+#define FPC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET)
+#define MTC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET)
+#define OTHERS_REG		__REG(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET)
+#define RST_STAT_REG		__REG(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
+#define WAKEUP_STAT_REG		__REG(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)
+#define BLK_PWR_STAT_REG	__REG(ELFIN_CLOCK_POWER_BASE+
+				      BLK_PWR_STAT_OFFSET)
+#define INF_REG0_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)
+#define INF_REG1_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET)
+#define INF_REG2_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET)
+#define INF_REG3_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET)
+#define INF_REG4_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET)
+#define INF_REG5_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET)
+#define INF_REG6_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET)
+#define INF_REG7_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET)
+
+#define APLL_LOCK	(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET)
+#define MPLL_LOCK	(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET)
+#define EPLL_LOCK	(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET)
+#define APLL_CON	(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET)
+#define MPLL_CON	(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET)
+#define EPLL_CON0	(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET)
+#define EPLL_CON1	(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET)
+#define CLK_SRC		(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET)
+#define CLK_DIV0	(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET)
+#define CLK_DIV1	(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET)
+#define CLK_DIV2	(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET)
+#define CLK_OUT		(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET)
+#define HCLK_GATE	(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET)
+#define PCLK_GATE	(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET)
+#define SCLK_GATE	(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET)
+#define AHB_CON0	(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET)
+#define AHB_CON1	(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET)
+#define AHB_CON2	(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET)
+#define SELECT_DMA	(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET)
+#define SW_RST		(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET)
+#define SYS_ID		(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET)
+#define MEM_SYS_CFG	(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET)
+#define QOS_OVERRIDE0	(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET)
+#define QOS_OVERRIDE1	(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET)
+#define MEM_CFG_STAT	(ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET)
+#define PWR_CFG		(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET)
+#define EINT_MASK	(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET)
+#define NOR_CFG		(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET)
+#define STOP_CFG	(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET)
+#define SLEEP_CFG	(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET)
+#define OSC_FREQ	(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET)
+#define OSC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET)
+#define PWR_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET)
+#define FPC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET)
+#define MTC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET)
+#define OTHERS		(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET)
+#define RST_STAT	(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
+#define WAKEUP_STAT	(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)
+#define BLK_PWR_STAT	(ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET)
+#define INF_REG0	(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)
+#define INF_REG1	(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET)
+#define INF_REG2	(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET)
+#define INF_REG3	(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET)
+#define INF_REG4	(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET)
+#define INF_REG5	(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET)
+#define INF_REG6	(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET)
+#define INF_REG7	(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET)
+
+
+/*
+ * GPIO
+ */
+#define ELFIN_GPIO_BASE		0x7f008000
+
+#define GPACON_OFFSET		0x00
+#define GPADAT_OFFSET		0x04
+#define GPAPUD_OFFSET		0x08
+#define GPACONSLP_OFFSET	0x0C
+#define GPAPUDSLP_OFFSET	0x10
+#define GPBCON_OFFSET		0x20
+#define GPBDAT_OFFSET		0x04
+#define GPBPUD_OFFSET		0x08
+#define GPBCONSLP_OFFSET	0x0C
+#define GPBPUDSLP_OFFSET	0x30
+#define GPCCON_OFFSET		0x40
+#define GPCDAT_OFFSET		0x44
+#define GPCPUD_OFFSET		0x48
+#define GPCCONSLP_OFFSET	0x4C
+#define GPCPUDSLP_OFFSET	0x50
+#define GPDCON_OFFSET		0x60
+#define GPDDAT_OFFSET		0x64
+#define GPDPUD_OFFSET		0x68
+#define GPDCONSLP_OFFSET	0x6C
+#define GPDPUDSLP_OFFSET	0x70
+#define GPECON_OFFSET		0x80
+#define GPEDAT_OFFSET		0x84
+#define GPEPUD_OFFSET		0x88
+#define GPECONSLP_OFFSET	0x8C
+#define GPEPUDSLP_OFFSET	0x90
+#define GPFCON_OFFSET		0xA0
+#define GPFDAT_OFFSET		0xA4
+#define GPFPUD_OFFSET		0xA8
+#define GPFCONSLP_OFFSET	0xAC
+#define GPFPUDSLP_OFFSET	0xB0
+#define GPGCON_OFFSET		0xC0
+#define GPGDAT_OFFSET		0xC4
+#define GPGPUD_OFFSET		0xC8
+#define GPGCONSLP_OFFSET	0xCC
+#define GPGPUDSLP_OFFSET	0xD0
+#define GPHCON0_OFFSET		0xE0
+#define GPHCON1_OFFSET		0xE4
+#define GPHDAT_OFFSET		0xE8
+#define GPHPUD_OFFSET		0xEC
+#define GPHCONSLP_OFFSET	0xF0
+#define GPHPUDSLP_OFFSET	0xF4
+#define GPICON_OFFSET		0x100
+#define GPIDAT_OFFSET		0x104
+#define GPIPUD_OFFSET		0x108
+#define GPICONSLP_OFFSET	0x10C
+#define GPIPUDSLP_OFFSET	0x110
+#define GPJCON_OFFSET		0x120
+#define GPJDAT_OFFSET		0x124
+#define GPJPUD_OFFSET		0x128
+#define GPJCONSLP_OFFSET	0x12C
+#define GPJPUDSLP_OFFSET	0x130
+#define MEM0DRVCON_OFFSET	0x1D0
+#define MEM1DRVCON_OFFSET	0x1D4
+#define GPKCON0_OFFSET		0x800
+#define GPKCON1_OFFSET		0x804
+#define GPKDAT_OFFSET		0x808
+#define GPKPUD_OFFSET		0x80C
+#define GPLCON0_OFFSET		0x810
+#define GPLCON1_OFFSET		0x814
+#define GPLDAT_OFFSET		0x818
+#define GPLPUD_OFFSET		0x81C
+#define GPMCON_OFFSET		0x820
+#define GPMDAT_OFFSET		0x824
+#define GPMPUD_OFFSET		0x828
+#define GPNCON_OFFSET		0x830
+#define GPNDAT_OFFSET		0x834
+#define GPNPUD_OFFSET		0x838
+#define GPOCON_OFFSET		0x140
+#define GPODAT_OFFSET		0x144
+#define GPOPUD_OFFSET		0x148
+#define GPOCONSLP_OFFSET	0x14C
+#define GPOPUDSLP_OFFSET	0x150
+#define GPPCON_OFFSET		0x160
+#define GPPDAT_OFFSET		0x164
+#define GPPPUD_OFFSET		0x168
+#define GPPCONSLP_OFFSET	0x16C
+#define GPPPUDSLP_OFFSET	0x170
+#define GPQCON_OFFSET		0x180
+#define GPQDAT_OFFSET		0x184
+#define GPQPUD_OFFSET		0x188
+#define GPQCONSLP_OFFSET	0x18C
+#define GPQPUDSLP_OFFSET	0x190
+
+#define EINTPEND_OFFSET		0x924
+
+#define GPACON_REG		__REG(ELFIN_GPIO_BASE+GPACON_OFFSET)
+#define GPADAT_REG		__REG(ELFIN_GPIO_BASE+GPADAT_OFFSET)
+#define GPAPUD_REG		__REG(ELFIN_GPIO_BASE+GPAPUD_OFFSET)
+#define GPACONSLP_REG		__REG(ELFIN_GPIO_BASE+GPACONSLP_OFFSET)
+#define GPAPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET)
+#define GPBCON_REG		__REG(ELFIN_GPIO_BASE+GPBCON_OFFSET)
+#define GPBDAT_REG		__REG(ELFIN_GPIO_BASE+GPBDAT_OFFSET)
+#define GPBPUD_REG		__REG(ELFIN_GPIO_BASE+GPBPUD_OFFSET)
+#define GPBCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET)
+#define GPBPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET)
+#define GPCCON_REG		__REG(ELFIN_GPIO_BASE+GPCCON_OFFSET)
+#define GPCDAT_REG		__REG(ELFIN_GPIO_BASE+GPCDAT_OFFSET)
+#define GPCPUD_REG		__REG(ELFIN_GPIO_BASE+GPCPUD_OFFSET)
+#define GPCCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET)
+#define GPCPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET)
+#define GPDCON_REG		__REG(ELFIN_GPIO_BASE+GPDCON_OFFSET)
+#define GPDDAT_REG		__REG(ELFIN_GPIO_BASE+GPDDAT_OFFSET)
+#define GPDPUD_REG		__REG(ELFIN_GPIO_BASE+GPDPUD_OFFSET)
+#define GPDCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET)
+#define GPDPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET)
+#define GPECON_REG		__REG(ELFIN_GPIO_BASE+GPECON_OFFSET)
+#define GPEDAT_REG		__REG(ELFIN_GPIO_BASE+GPEDAT_OFFSET)
+#define GPEPUD_REG		__REG(ELFIN_GPIO_BASE+GPEPUD_OFFSET)
+#define GPECONSLP_REG		__REG(ELFIN_GPIO_BASE+GPECONSLP_OFFSET)
+#define GPEPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET)
+#define GPFCON_REG		__REG(ELFIN_GPIO_BASE+GPFCON_OFFSET)
+#define GPFDAT_REG		__REG(ELFIN_GPIO_BASE+GPFDAT_OFFSET)
+#define GPFPUD_REG		__REG(ELFIN_GPIO_BASE+GPFPUD_OFFSET)
+#define GPFCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET)
+#define GPFPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET)
+#define GPGCON_REG		__REG(ELFIN_GPIO_BASE+GPGCON_OFFSET)
+#define GPGDAT_REG		__REG(ELFIN_GPIO_BASE+GPGDAT_OFFSET)
+#define GPGPUD_REG		__REG(ELFIN_GPIO_BASE+GPGPUD_OFFSET)
+#define GPGCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET)
+#define GPGPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET)
+#define GPHCON0_REG		__REG(ELFIN_GPIO_BASE+GPHCON0_OFFSET)
+#define GPHCON1_REG		__REG(ELFIN_GPIO_BASE+GPHCON1_OFFSET)
+#define GPHDAT_REG		__REG(ELFIN_GPIO_BASE+GPHDAT_OFFSET)
+#define GPHPUD_REG		__REG(ELFIN_GPIO_BASE+GPHPUD_OFFSET)
+#define GPHCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET)
+#define GPHPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET)
+#define GPICON_REG		__REG(ELFIN_GPIO_BASE+GPICON_OFFSET)
+#define GPIDAT_REG		__REG(ELFIN_GPIO_BASE+GPIDAT_OFFSET)
+#define GPIPUD_REG		__REG(ELFIN_GPIO_BASE+GPIPUD_OFFSET)
+#define GPICONSLP_REG		__REG(ELFIN_GPIO_BASE+GPICONSLP_OFFSET)
+#define GPIPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET)
+#define GPJCON_REG		__REG(ELFIN_GPIO_BASE+GPJCON_OFFSET)
+#define GPJDAT_REG		__REG(ELFIN_GPIO_BASE+GPJDAT_OFFSET)
+#define GPJPUD_REG		__REG(ELFIN_GPIO_BASE+GPJPUD_OFFSET)
+#define GPJCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET)
+#define GPJPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET)
+#define GPKCON0_REG		__REG(ELFIN_GPIO_BASE+GPKCON0_OFFSET)
+#define GPKCON1_REG		__REG(ELFIN_GPIO_BASE+GPKCON1_OFFSET)
+#define GPKDAT_REG		__REG(ELFIN_GPIO_BASE+GPKDAT_OFFSET)
+#define GPKPUD_REG		__REG(ELFIN_GPIO_BASE+GPKPUD_OFFSET)
+#define GPLCON0_REG		__REG(ELFIN_GPIO_BASE+GPLCON0_OFFSET)
+#define GPLCON1_REG		__REG(ELFIN_GPIO_BASE+GPLCON1_OFFSET)
+#define GPLDAT_REG		__REG(ELFIN_GPIO_BASE+GPLDAT_OFFSET)
+#define GPLPUD_REG		__REG(ELFIN_GPIO_BASE+GPLPUD_OFFSET)
+#define GPMCON_REG		__REG(ELFIN_GPIO_BASE+GPMCON_OFFSET)
+#define GPMDAT_REG		__REG(ELFIN_GPIO_BASE+GPMDAT_OFFSET)
+#define GPMPUD_REG		__REG(ELFIN_GPIO_BASE+GPMPUD_OFFSET)
+#define GPNCON_REG		__REG(ELFIN_GPIO_BASE+GPNCON_OFFSET)
+#define GPNDAT_REG		__REG(ELFIN_GPIO_BASE+GPNDAT_OFFSET)
+#define GPNPUD_REG		__REG(ELFIN_GPIO_BASE+GPNPUD_OFFSET)
+#define GPOCON_REG		__REG(ELFIN_GPIO_BASE+GPOCON_OFFSET)
+#define GPODAT_REG		__REG(ELFIN_GPIO_BASE+GPODAT_OFFSET)
+#define GPOPUD_REG		__REG(ELFIN_GPIO_BASE+GPOPUD_OFFSET)
+#define GPOCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET)
+#define GPOPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET)
+#define GPPCON_REG		__REG(ELFIN_GPIO_BASE+GPPCON_OFFSET)
+#define GPPDAT_REG		__REG(ELFIN_GPIO_BASE+GPPDAT_OFFSET)
+#define GPPPUD_REG		__REG(ELFIN_GPIO_BASE+GPPPUD_OFFSET)
+#define GPPCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET)
+#define GPPPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET)
+#define GPQCON_REG		__REG(ELFIN_GPIO_BASE+GPQCON_OFFSET)
+#define GPQDAT_REG		__REG(ELFIN_GPIO_BASE+GPQDAT_OFFSET)
+#define GPQPUD_REG		__REG(ELFIN_GPIO_BASE+GPQPUD_OFFSET)
+#define GPQCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET)
+#define GPQPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET)
+
+/*
+ * Bus Matrix
+ */
+#define ELFIN_MEM_SYS_CFG      0x7e00f120
+
+#define GPACON		(ELFIN_GPIO_BASE+GPACON_OFFSET)
+#define GPADAT		(ELFIN_GPIO_BASE+GPADAT_OFFSET)
+#define GPAPUD		(ELFIN_GPIO_BASE+GPAPUD_OFFSET)
+#define GPACONSLP	(ELFIN_GPIO_BASE+GPACONSLP_OFFSET)
+#define GPAPUDSLP	(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET)
+#define GPBCON		(ELFIN_GPIO_BASE+GPBCON_OFFSET)
+#define GPBDAT		(ELFIN_GPIO_BASE+GPBDAT_OFFSET)
+#define GPBPUD		(ELFIN_GPIO_BASE+GPBPUD_OFFSET)
+#define GPBCONSLP	(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET)
+#define GPBPUDSLP	(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET)
+#define GPCCON		(ELFIN_GPIO_BASE+GPCCON_OFFSET)
+#define GPCDAT		(ELFIN_GPIO_BASE+GPCDAT_OFFSET)
+#define GPCPUD		(ELFIN_GPIO_BASE+GPCPUD_OFFSET)
+#define GPCCONSLP	(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET)
+#define GPCPUDSLP	(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET)
+#define GPDCON		(ELFIN_GPIO_BASE+GPDCON_OFFSET)
+#define GPDDAT		(ELFIN_GPIO_BASE+GPDDAT_OFFSET)
+#define GPDPUD		(ELFIN_GPIO_BASE+GPDPUD_OFFSET)
+#define GPDCONSLP	(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET)
+#define GPDPUDSLP	(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET)
+#define GPECON		(ELFIN_GPIO_BASE+GPECON_OFFSET)
+#define GPEDAT		(ELFIN_GPIO_BASE+GPEDAT_OFFSET)
+#define GPEPUD		(ELFIN_GPIO_BASE+GPEPUD_OFFSET)
+#define GPECONSLP	(ELFIN_GPIO_BASE+GPECONSLP_OFFSET)
+#define GPEPUDSLP	(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET)
+#define GPFCON		(ELFIN_GPIO_BASE+GPFCON_OFFSET)
+#define GPFDAT		(ELFIN_GPIO_BASE+GPFDAT_OFFSET)
+#define GPFPUD		(ELFIN_GPIO_BASE+GPFPUD_OFFSET)
+#define GPFCONSLP	(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET)
+#define GPFPUDSLP	(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET)
+#define GPGCON		(ELFIN_GPIO_BASE+GPGCON_OFFSET)
+#define GPGDAT		(ELFIN_GPIO_BASE+GPGDAT_OFFSET)
+#define GPGPUD		(ELFIN_GPIO_BASE+GPGPUD_OFFSET)
+#define GPGCONSLP	(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET)
+#define GPGPUDSLP	(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET)
+#define GPHCON0		(ELFIN_GPIO_BASE+GPHCON0_OFFSET)
+#define GPHCON1		(ELFIN_GPIO_BASE+GPHCON1_OFFSET)
+#define GPHDAT		(ELFIN_GPIO_BASE+GPHDAT_OFFSET)
+#define GPHPUD		(ELFIN_GPIO_BASE+GPHPUD_OFFSET)
+#define GPHCONSLP	(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET)
+#define GPHPUDSLP	(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET)
+#define GPICON		(ELFIN_GPIO_BASE+GPICON_OFFSET)
+#define GPIDAT		(ELFIN_GPIO_BASE+GPIDAT_OFFSET)
+#define GPIPUD		(ELFIN_GPIO_BASE+GPIPUD_OFFSET)
+#define GPICONSLP	(ELFIN_GPIO_BASE+GPICONSLP_OFFSET)
+#define GPIPUDSLP	(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET)
+#define GPJCON		(ELFIN_GPIO_BASE+GPJCON_OFFSET)
+#define GPJDAT		(ELFIN_GPIO_BASE+GPJDAT_OFFSET)
+#define GPJPUD		(ELFIN_GPIO_BASE+GPJPUD_OFFSET)
+#define GPJCONSLP	(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET)
+#define GPJPUDSLP	(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET)
+#define GPKCON0		(ELFIN_GPIO_BASE+GPKCON0_OFFSET)
+#define GPKCON1		(ELFIN_GPIO_BASE+GPKCON1_OFFSET)
+#define GPKDAT		(ELFIN_GPIO_BASE+GPKDAT_OFFSET)
+#define GPKPUD		(ELFIN_GPIO_BASE+GPKPUD_OFFSET)
+#define GPLCON0		(ELFIN_GPIO_BASE+GPLCON0_OFFSET)
+#define GPLCON1		(ELFIN_GPIO_BASE+GPLCON1_OFFSET)
+#define GPLDAT		(ELFIN_GPIO_BASE+GPLDAT_OFFSET)
+#define GPLPUD		(ELFIN_GPIO_BASE+GPLPUD_OFFSET)
+#define GPMCON		(ELFIN_GPIO_BASE+GPMCON_OFFSET)
+#define GPMDAT		(ELFIN_GPIO_BASE+GPMDAT_OFFSET)
+#define GPMPUD		(ELFIN_GPIO_BASE+GPMPUD_OFFSET)
+#define GPNCON		(ELFIN_GPIO_BASE+GPNCON_OFFSET)
+#define GPNDAT		(ELFIN_GPIO_BASE+GPNDAT_OFFSET)
+#define GPNPUD		(ELFIN_GPIO_BASE+GPNPUD_OFFSET)
+#define GPOCON		(ELFIN_GPIO_BASE+GPOCON_OFFSET)
+#define GPODAT		(ELFIN_GPIO_BASE+GPODAT_OFFSET)
+#define GPOPUD		(ELFIN_GPIO_BASE+GPOPUD_OFFSET)
+#define GPOCONSLP	(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET)
+#define GPOPUDSLP	(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET)
+#define GPPCON		(ELFIN_GPIO_BASE+GPPCON_OFFSET)
+#define GPPDAT		(ELFIN_GPIO_BASE+GPPDAT_OFFSET)
+#define GPPPUD		(ELFIN_GPIO_BASE+GPPPUD_OFFSET)
+#define GPPCONSLP	(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET)
+#define GPPPUDSLP	(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET)
+#define GPQCON		(ELFIN_GPIO_BASE+GPQCON_OFFSET)
+#define GPQDAT		(ELFIN_GPIO_BASE+GPQDAT_OFFSET)
+#define GPQPUD		(ELFIN_GPIO_BASE+GPQPUD_OFFSET)
+#define GPQCONSLP	(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET)
+#define GPQPUDSLP	(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET)
+
+/*
+ * Memory controller
+ */
+#define ELFIN_SROM_BASE                0x70000000
+
+#define SROM_BW_REG            __REG(ELFIN_SROM_BASE+0x0)
+#define SROM_BC0_REG           __REG(ELFIN_SROM_BASE+0x4)
+#define SROM_BC1_REG           __REG(ELFIN_SROM_BASE+0x8)
+#define SROM_BC2_REG           __REG(ELFIN_SROM_BASE+0xC)
+#define SROM_BC3_REG           __REG(ELFIN_SROM_BASE+0x10)
+#define SROM_BC4_REG           __REG(ELFIN_SROM_BASE+0x14)
+#define SROM_BC5_REG           __REG(ELFIN_SROM_BASE+0x18)
+
+/*
+ * SDRAM Controller
+ */
+#define ELFIN_DMC0_BASE		0x7e000000
+#define ELFIN_DMC1_BASE		0x7e001000
+
+#define INDEX_DMC_MEMC_STATUS   (0x00)
+#define INDEX_DMC_MEMC_CMD      (0x04)
+#define INDEX_DMC_DIRECT_CMD    (0x08)
+#define INDEX_DMC_MEMORY_CFG    (0x0C)
+#define INDEX_DMC_REFRESH_PRD   (0x10)
+#define INDEX_DMC_CAS_LATENCY   (0x14)
+#define INDEX_DMC_T_DQSS        (0x18)
+#define INDEX_DMC_T_MRD         (0x1C)
+#define INDEX_DMC_T_RAS         (0x20)
+#define INDEX_DMC_T_RC          (0x24)
+#define INDEX_DMC_T_RCD         (0x28)
+#define INDEX_DMC_T_RFC         (0x2C)
+#define INDEX_DMC_T_RP          (0x30)
+#define INDEX_DMC_T_RRD         (0x34)
+#define INDEX_DMC_T_WR          (0x38)
+#define INDEX_DMC_T_WTR         (0x3C)
+#define INDEX_DMC_T_XP          (0x40)
+#define INDEX_DMC_T_XSR         (0x44)
+#define INDEX_DMC_T_ESR         (0x48)
+#define INDEX_DMC_MEMORY_CFG2	(0x4C)
+#define INDEX_DMC_CHIP_0_CFG    (0x200)
+#define INDEX_DMC_CHIP_1_CFG    (0x204)
+#define INDEX_DMC_CHIP_2_CFG    (0x208)
+#define INDEX_DMC_CHIP_3_CFG    (0x20C)
+#define INDEX_DMC_USER_STATUS	(0x300)
+#define INDEX_DMC_USER_CONFIG	(0x304)
+
+/*
+ * Memory Chip direct command
+ */
+#define DMC_NOP0	0x0c0000
+#define DMC_NOP1	0x1c0000
+#define DMC_PA0		0x000000        /* Precharge all */
+#define DMC_PA1		0x100000
+#define DMC_AR0		0x040000        /* Autorefresh */
+#define DMC_AR1		0x140000
+#define DMC_SDR_MR0	0x080032        /* MRS, CAS 3,  Burst Length 4 */
+#define DMC_SDR_MR1	0x180032
+#define DMC_DDR_MR0	0x080162
+#define DMC_DDR_MR1	0x180162
+#define DMC_mDDR_MR0	0x080032        /* CAS 3, Burst Length 4 */
+#define DMC_mDDR_MR1	0x180032
+#define DMC_mSDR_EMR0	0x0a0000        /* EMRS, DS:Full, PASR:Full Array */
+#define DMC_mSDR_EMR1	0x1a0000
+#define DMC_DDR_EMR0	0x090000
+#define DMC_DDR_EMR1	0x190000
+#define DMC_mDDR_EMR0	0x0a0000        /*  DS:Full, PASR:Full Array */
+#define DMC_mDDR_EMR1	0x1a0000
+
+/****************************************************************
+ Definitions for memory configuration
+ Set memory configuration
+	active_chips	 = 1'b0 (1 chip)
+	qos_master_chip  = 3'b000(ARID[3:0])
+	memory burst	 = 3'b010(burst 4)
+	stop_mem_clock	 = 1'b0(disable dynamical stop)
+	auto_power_down  = 1'b0(disable auto power-down mode)
+	power_down_prd	 = 6'b00_0000(0 cycle for auto power-down)
+	ap_bit		 = 1'b0 (bit position of auto-precharge is 10)
+	row_bits	 = 3'b010(# row address 13)
+	column_bits	 = 3'b010(# column address 10 )
+
+ Set user configuration
+	2'b10=SDRAM/mSDRAM, 2'b11=DDR, 2'b01=mDDR
+
+ Set chip select for chip [n]
+	 row bank control, bank address 0x3000_0000 ~ 0x37ff_ffff
+	 CHIP_[n]_CFG=0x30F8,  30: ADDR[31:24], F8: Mask[31:24]
+******************************************************************/
+
+/*
+ * Nand flash controller
+ */
+#define ELFIN_NAND_BASE		0x70200000
+
+#define NFCONF_OFFSET           0x00
+#define NFCONT_OFFSET           0x04
+#define NFCMMD_OFFSET           0x08
+#define NFADDR_OFFSET           0x0c
+#define NFDATA_OFFSET		0x10
+#define NFMECCDATA0_OFFSET      0x14
+#define NFMECCDATA1_OFFSET      0x18
+#define NFSECCDATA0_OFFSET      0x1c
+#define NFSBLK_OFFSET           0x20
+#define NFEBLK_OFFSET           0x24
+#define NFSTAT_OFFSET           0x28
+#define NFESTAT0_OFFSET         0x2c
+#define NFESTAT1_OFFSET         0x30
+#define NFMECC0_OFFSET          0x34
+#define NFMECC1_OFFSET          0x38
+#define NFSECC_OFFSET           0x3c
+#define NFMLCBITPT_OFFSET       0x40
+
+#define NFCONF			(ELFIN_NAND_BASE+NFCONF_OFFSET)
+#define NFCONT			(ELFIN_NAND_BASE+NFCONT_OFFSET)
+#define NFCMMD			(ELFIN_NAND_BASE+NFCMMD_OFFSET)
+#define NFADDR           	(ELFIN_NAND_BASE+NFADDR_OFFSET)
+#define NFDATA          	(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFMECCDATA0     	(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
+#define NFMECCDATA1     	(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
+#define NFSECCDATA0      	(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
+#define NFSBLK          	(ELFIN_NAND_BASE+NFSBLK_OFFSET)
+#define NFEBLK           	(ELFIN_NAND_BASE+NFEBLK_OFFSET)
+#define NFSTAT           	(ELFIN_NAND_BASE+NFSTAT_OFFSET)
+#define NFESTAT0         	(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
+#define NFESTAT1         	(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
+#define NFMECC0          	(ELFIN_NAND_BASE+NFMECC0_OFFSET)
+#define NFMECC1          	(ELFIN_NAND_BASE+NFMECC1_OFFSET)
+#define NFSECC           	(ELFIN_NAND_BASE+NFSECC_OFFSET)
+#define NFMLCBITPT           	(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
+
+#define NFCONF_REG		__REG(ELFIN_NAND_BASE+NFCONF_OFFSET)
+#define NFCONT_REG		__REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
+#define NFCMD_REG		__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
+#define NFADDR_REG           	__REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
+#define NFDATA_REG          	__REG(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFDATA8_REG          	__REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFMECCDATA0_REG     	__REG(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
+#define NFMECCDATA1_REG     	__REG(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
+#define NFSECCDATA0_REG      	__REG(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
+#define NFSBLK_REG          	__REG(ELFIN_NAND_BASE+NFSBLK_OFFSET)
+#define NFEBLK_REG           	__REG(ELFIN_NAND_BASE+NFEBLK_OFFSET)
+#define NFSTAT_REG           	__REG(ELFIN_NAND_BASE+NFSTAT_OFFSET)
+#define NFESTAT0_REG         	__REG(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
+#define NFESTAT1_REG         	__REG(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
+#define NFMECC0_REG          	__REG(ELFIN_NAND_BASE+NFMECC0_OFFSET)
+#define NFMECC1_REG          	__REG(ELFIN_NAND_BASE+NFMECC1_OFFSET)
+#define NFSECC_REG           	__REG(ELFIN_NAND_BASE+NFSECC_OFFSET)
+#define NFMLCBITPT_REG         	__REG(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
+
+#define NFCONF_ECC_4BIT		(1<<24)
+
+#define NFCONT_ECC_ENC		(1<<18)
+#define NFCONT_WP		(1<<16)
+#define NFCONT_MECCLOCK		(1<<7)
+#define NFCONT_SECCLOCK		(1<<6)
+#define NFCONT_INITMECC		(1<<5)
+#define NFCONT_INITSECC		(1<<4)
+#define NFCONT_INITECC		(NFCONT_INITMECC | NFCONT_INITSECC)
+#define NFCONT_CS_ALT		(1<<2)
+#define NFCONT_CS		(1<<1)
+#define NFCONT_ENABLE		(1<<0)
+
+#define NFSTAT_ECCENCDONE	(1<<7)
+#define NFSTAT_ECCDECDONE	(1<<6)
+#define NFSTAT_RnB		(1<<0)
+
+#define NFESTAT0_ECCBUSY	(1<<31)
+
+/*
+ * Interrupt
+ */
+#define ELFIN_VIC0_BASE_ADDR	0x71200000
+#define ELFIN_VIC1_BASE_ADDR	0x71300000
+#define oINTMOD			0x0C  /* VIC INT SELECT (IRQ or FIQ) */
+#define oINTUNMSK		0x10  /* VIC INT EN (Unmask by writing 1) */
+#define oINTMSK			0x14  /* VIC INT EN CLEAR (Mask by writing 1) */
+#define oINTSUBMSK		0x1C  /* VIC SOFT INT CLEAR */
+#define oVECTADDR		0xF00 /* VIC ADDRESS */
+
+/*
+ * Watchdog timer
+ */
+#define ELFIN_WATCHDOG_BASE	0x7E004000
+
+#define WTCON_REG		__REG(0x7E004004)
+#define WTDAT_REG		__REG(0x7E004008)
+#define WTCNT_REG		__REG(0x7E00400C)
+
+
+/*
+ * UART
+ */
+#define ELFIN_UART_BASE		0x7F005000
+
+#define ELFIN_UART0_OFFSET	0x0000
+#define ELFIN_UART1_OFFSET	0x0400
+#define ELFIN_UART2_OFFSET	0x0800
+
+#define ULCON_OFFSET		0x00
+#define UCON_OFFSET		0x04
+#define UFCON_OFFSET		0x08
+#define UMCON_OFFSET		0x0C
+#define UTRSTAT_OFFSET		0x10
+#define UERSTAT_OFFSET		0x14
+#define UFSTAT_OFFSET		0x18
+#define UMSTAT_OFFSET		0x1C
+#define UTXH_OFFSET		0x20
+#define URXH_OFFSET		0x24
+#define UBRDIV_OFFSET		0x28
+#define UDIVSLOT_OFFSET		0x2C
+#define UINTP_OFFSET		0x30
+#define UINTSP_OFFSET		0x34
+#define UINTM_OFFSET		0x38
+
+#define ULCON0_REG		__REG(0x7F005000)
+#define UCON0_REG		__REG(0x7F005004)
+#define UFCON0_REG		__REG(0x7F005008)
+#define UMCON0_REG		__REG(0x7F00500C)
+#define UTRSTAT0_REG		__REG(0x7F005010)
+#define UERSTAT0_REG		__REG(0x7F005014)
+#define UFSTAT0_REG		__REG(0x7F005018)
+#define UMSTAT0_REG		__REG(0x7F00501c)
+#define UTXH0_REG		__REG(0x7F005020)
+#define URXH0_REG		__REG(0x7F005024)
+#define UBRDIV0_REG		__REG(0x7F005028)
+#define UDIVSLOT0_REG		__REG(0x7F00502c)
+#define UINTP0_REG		__REG(0x7F005030)
+#define UINTSP0_REG		__REG(0x7F005034)
+#define UINTM0_REG		__REG(0x7F005038)
+
+#define ULCON1_REG		__REG(0x7F005400)
+#define UCON1_REG		__REG(0x7F005404)
+#define UFCON1_REG		__REG(0x7F005408)
+#define UMCON1_REG		__REG(0x7F00540C)
+#define UTRSTAT1_REG		__REG(0x7F005410)
+#define UERSTAT1_REG		__REG(0x7F005414)
+#define UFSTAT1_REG		__REG(0x7F005418)
+#define UMSTAT1_REG		__REG(0x7F00541c)
+#define UTXH1_REG		__REG(0x7F005420)
+#define URXH1_REG		__REG(0x7F005424)
+#define UBRDIV1_REG		__REG(0x7F005428)
+#define UDIVSLOT1_REG		__REG(0x7F00542c)
+#define UINTP1_REG		__REG(0x7F005430)
+#define UINTSP1_REG		__REG(0x7F005434)
+#define UINTM1_REG		__REG(0x7F005438)
+
+#define UTRSTAT_TX_EMPTY	(1 << 2)
+#define UTRSTAT_RX_READY	(1 << 0)
+#define UART_ERR_MASK		0xF
+
+/*
+ * PWM timer
+ */
+#define ELFIN_TIMER_BASE       0x7F006000
+
+#define TCFG0_REG              __REG(0x7F006000)
+#define TCFG1_REG              __REG(0x7F006004)
+#define TCON_REG               __REG(0x7F006008)
+#define TCNTB0_REG             __REG(0x7F00600c)
+#define TCMPB0_REG             __REG(0x7F006010)
+#define TCNTO0_REG             __REG(0x7F006014)
+#define TCNTB1_REG             __REG(0x7F006018)
+#define TCMPB1_REG             __REG(0x7F00601c)
+#define TCNTO1_REG             __REG(0x7F006020)
+#define TCNTB2_REG             __REG(0x7F006024)
+#define TCMPB2_REG             __REG(0x7F006028)
+#define TCNTO2_REG             __REG(0x7F00602c)
+#define TCNTB3_REG             __REG(0x7F006030)
+#define TCMPB3_REG             __REG(0x7F006034)
+#define TCNTO3_REG             __REG(0x7F006038)
+#define TCNTB4_REG             __REG(0x7F00603c)
+#define TCNTO4_REG             __REG(0x7F006040)
+
+/* Fields */
+#define fTCFG0_DZONE           Fld(8, 16) /* the dead zone length (= timer 0) */
+#define fTCFG0_PRE1            Fld(8, 8)  /* prescaler value for time 2,3,4 */
+#define fTCFG0_PRE0            Fld(8, 0)  /* prescaler value for time 0,1 */
+#define fTCFG1_MUX4            Fld(4, 16)
+/* bits */
+#define TCFG0_DZONE(x)         FInsrt((x), fTCFG0_DZONE)
+#define TCFG0_PRE1(x)          FInsrt((x), fTCFG0_PRE1)
+#define TCFG0_PRE0(x)          FInsrt((x), fTCFG0_PRE0)
+#define TCON_4_AUTO            (1 << 22)  /* auto reload on/off for Timer 4 */
+#define TCON_4_UPDATE          (1 << 21)  /* manual Update TCNTB4 */
+#define TCON_4_ONOFF           (1 << 20)  /* 0: Stop, 1: start Timer 4 */
+#define COUNT_4_ON             (TCON_4_ONOFF * 1)
+#define COUNT_4_OFF            (TCON_4_ONOFF * 0)
+#define TCON_3_AUTO            (1 << 19)  /* auto reload on/off for Timer 3 */
+#define TIMER3_ATLOAD_ON       (TCON_3_AUTO * 1)
+#define TIMER3_ATLAOD_OFF      FClrBit(TCON, TCON_3_AUTO)
+#define TCON_3_INVERT          (1 << 18)  /* 1: Inverter on for TOUT3 */
+#define TIMER3_IVT_ON          (TCON_3_INVERT * 1)
+#define TIMER3_IVT_OFF         (FClrBit(TCON, TCON_3_INVERT))
+#define TCON_3_MAN             (1 << 17)  /* manual Update TCNTB3,TCMPB3 */
+#define TIMER3_MANUP           (TCON_3_MAN*1)
+#define TIMER3_NOP             (FClrBit(TCON, TCON_3_MAN))
+#define TCON_3_ONOFF           (1 << 16)  /* 0: Stop, 1: start Timer 3 */
+#define TIMER3_ON              (TCON_3_ONOFF * 1)
+#define TIMER3_OFF             (FClrBit(TCON, TCON_3_ONOFF))
+
+#if defined(CONFIG_CLK_400_100_50)
+#define Startup_AMDIV		400
+#define Startup_MDIV		400
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_400_133_66)
+#define Startup_AMDIV		400
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_533_133_66)
+#define Startup_AMDIV		533
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_667_133_66)
+#define Startup_AMDIV		667
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#endif
+
+#define	Startup_PCLKdiv		3
+#define Startup_HCLKx2div	1
+#define Startup_HCLKdiv		1
+#define Startup_MPLLdiv		1
+#define Startup_APLLdiv		0
+
+#define CLK_DIV_VAL	((Startup_PCLKdiv << 12) | (Startup_HCLKx2div << 9)| \
+	(Startup_HCLKdiv << 8) | (Startup_MPLLdiv<<4) | Startup_APLLdiv)
+#define MPLL_VAL	((1 << 31) | (Startup_MDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_MPLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_MDIV)
+
+#if defined(CONFIG_SYNC_MODE)
+#define APLL_VAL	((1 << 31) | (Startup_MDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_APLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_MDIV)
+#define Startup_HCLK	(Startup_MPLL / (Startup_HCLKx2div + 1) / \
+	(Startup_HCLKdiv + 1))
+#else
+#define APLL_VAL	((1 << 31) | (Startup_AMDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_APLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_AMDIV)
+#define Startup_HCLK	(Startup_MPLL / (Startup_HCLKx2div + 1) / \
+	(Startup_HCLKdiv + 1))
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define DMC1_MEM_CFG	0x80010012	/* Chip1, Burst4, Row/Column bit */
+#define DMC1_MEM_CFG2	0xB45
+#define DMC1_CHIP0_CFG	0x150F8		/* 0x4000_0000 ~ 0x43ff_ffff (64MB) */
+#define DMC_DDR_32_CFG	0x0 		/* 32bit, DDR */
+
+/* Memory Parameters */
+/* DDR Parameters */
+#define DDR_tREFRESH		7800	/* ns */
+#define DDR_tRAS		45	/* ns (min: 45ns)*/
+#define DDR_tRC 		68	/* ns (min: 67.5ns)*/
+#define DDR_tRCD		23	/* ns (min: 22.5ns)*/
+#define DDR_tRFC		80	/* ns (min: 80ns)*/
+#define DDR_tRP 		23	/* ns (min: 22.5ns)*/
+#define DDR_tRRD		15	/* ns (min: 15ns)*/
+#define DDR_tWR 		15	/* ns (min: 15ns)*/
+#define DDR_tXSR		120	/* ns (min: 120ns)*/
+#define DDR_CASL		3	/* CAS Latency 3 */
+
+/*
+ * mDDR memory configuration
+ */
+#define DMC_DDR_BA_EMRS 	2
+#define DMC_DDR_MEM_CASLAT	3
+/* 6   Set Cas Latency to 3 */
+#define DMC_DDR_CAS_LATENCY	(DDR_CASL << 1)
+/* Min 0.75 ~ 1.25 */
+#define DMC_DDR_t_DQSS		1
+/* Min 2 tck */
+#define DMC_DDR_t_MRD		2
+/* 7, Min 45ns */
+#define DMC_DDR_t_RAS		(((Startup_HCLK/1000*DDR_tRAS)-1)/1000000+1)
+/* 10, Min 67.5ns */
+#define DMC_DDR_t_RC		(((Startup_HCLK/1000*DDR_tRC)-1)/1000000+1)
+/* 4,5(TRM), Min 22.5ns */
+#define DMC_DDR_t_RCD		(((Startup_HCLK/1000*DDR_tRCD)-1)/1000000+1)
+#define DMC_DDR_schedule_RCD	((DMC_DDR_t_RCD - 3) << 3)
+/* 11,18(TRM) Min 80ns */
+#define DMC_DDR_t_RFC		(((Startup_HCLK/1000*DDR_tRFC)-1)/1000000+1)
+#define DMC_DDR_schedule_RFC	((DMC_DDR_t_RFC - 3) << 5)
+/* 4, 5(TRM) Min 22.5ns */
+#define DMC_DDR_t_RP		(((Startup_HCLK/1000*DDR_tRP)-1)/1000000+1)
+#define DMC_DDR_schedule_RP	((DMC_DDR_t_RP - 3) << 3)
+/* 3, Min 15ns */
+#define DMC_DDR_t_RRD		(((Startup_HCLK/1000*DDR_tRRD)-1)/1000000+1)
+/* Min 15ns */
+#define DMC_DDR_t_WR		(((Startup_HCLK/1000*DDR_tWR)-1)/1000000+1)
+#define DMC_DDR_t_WTR		2
+/* 1tck + tIS(1.5ns) */
+#define DMC_DDR_t_XP		2
+/* 17, Min 120ns */
+#define DMC_DDR_t_XSR		(((Startup_HCLK/1000*DDR_tXSR)-1)/1000000+1)
+#define DMC_DDR_t_ESR		DMC_DDR_t_XSR
+/* TRM 2656 */
+#define DMC_DDR_REFRESH_PRD	(((Startup_HCLK/1000*DDR_tREFRESH)-1)/1000000)
+/* 2b01 : mDDR */
+#define DMC_DDR_USER_CONFIG	1
+
+#ifndef __ASSEMBLY__
+enum s3c64xx_uarts_nr {
+	S3C64XX_UART0,
+	S3C64XX_UART1,
+	S3C64XX_UART2,
+};
+
+#include "s3c64x0.h"
+
+static inline s3c64xx_uart *s3c64xx_get_base_uart(enum s3c64xx_uarts_nr nr)
+{
+	return (s3c64xx_uart *)(ELFIN_UART_BASE + (nr * 0x400));
+}
+#endif
+
+#endif /*__S3C6400_H__*/
diff --git a/include/s3c64x0.h b/include/s3c64x0.h
new file mode 100644
index 0000000..ba6802a
--- /dev/null
+++ b/include/s3c64x0.h
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2003
+ * David M??ller ELSOFT AG Switzerland. d.mueller at elsoft.ch
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+ */
+
+/************************************************
+ * NAME	    : S3C64XX.h
+ * Version  : 31.3.2003
+ *
+ * common stuff for SAMSUNG S3C64XX SoC
+ ************************************************/
+
+#ifndef __S3C64XX_H__
+#define __S3C64XX_H__
+
+#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400)
+#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your configuration!
+#endif
+
+typedef vu_char		S3C64XX_REG8;
+typedef vu_short	S3C64XX_REG16;
+typedef vu_long		S3C64XX_REG32;
+
+/* UART (see manual chapter 11) */
+typedef struct {
+	S3C64XX_REG32	ULCON;
+	S3C64XX_REG32	UCON;
+	S3C64XX_REG32	UFCON;
+	S3C64XX_REG32	UMCON;
+	S3C64XX_REG32	UTRSTAT;
+	S3C64XX_REG32	UERSTAT;
+	S3C64XX_REG32	UFSTAT;
+	S3C64XX_REG32	UMSTAT;
+#ifdef __BIG_ENDIAN
+	S3C64XX_REG8	res1[3];
+	S3C64XX_REG8	UTXH;
+	S3C64XX_REG8	res2[3];
+	S3C64XX_REG8	URXH;
+#else /* Little Endian */
+	S3C64XX_REG8	UTXH;
+	S3C64XX_REG8	res1[3];
+	S3C64XX_REG8	URXH;
+	S3C64XX_REG8	res2[3];
+#endif
+	S3C64XX_REG32	UBRDIV;
+#ifdef __BIG_ENDIAN
+	S3C64XX_REG8	res3[2];
+	S3C64XX_REG16	UDIVSLOT;
+#else
+	S3C64XX_REG16	UDIVSLOT;
+	S3C64XX_REG8	res3[2];
+#endif
+} /*__attribute__((__packed__))*/ s3c64xx_uart;
+
+/* PWM TIMER (see manual chapter 10) */
+typedef struct {
+	S3C64XX_REG32	TCNTB;
+	S3C64XX_REG32	TCMPB;
+	S3C64XX_REG32	TCNTO;
+} /*__attribute__((__packed__))*/ s3c64xx_timer;
+
+typedef struct {
+	S3C64XX_REG32	TCFG0;
+	S3C64XX_REG32	TCFG1;
+	S3C64XX_REG32	TCON;
+	s3c64xx_timer	ch[4];
+	S3C64XX_REG32	TCNTB4;
+	S3C64XX_REG32	TCNTO4;
+} /*__attribute__((__packed__))*/ s3c64xx_timers;
+
+#endif /*__S3C64XX_H__*/
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 4/7 v3] USB: Add support for OHCI controller on s3c6400
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
                             ` (2 preceding siblings ...)
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 3/7 v3] ARM: Add arm1176 core with s3c6400 SoC Guennadi Liakhovetski
@ 2008-08-04 12:45           ` Guennadi Liakhovetski
  2008-08-04 21:08             ` Jean-Christophe PLAGNIOL-VILLARD
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver Guennadi Liakhovetski
                             ` (2 subsequent siblings)
  6 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:45 UTC (permalink / raw)
  To: u-boot

Notice: USB on s3c6400 currently works _only_ with switched off MMU. One could
try to enable the MMU, but map addresses 1-to-1, and disable data cache, then
it should work too and we could still profit from instruction cache.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 cpu/arm1176/s3c64xx/Makefile |    1 +
 cpu/arm1176/s3c64xx/usb.c    |   45 ++++++++++++++++++++++++++++++++++++++++++
 drivers/usb/usb_ohci.c       |    1 +
 3 files changed, 47 insertions(+), 0 deletions(-)
 create mode 100644 cpu/arm1176/s3c64xx/usb.c

diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile
index fa4ee3f..4ab1811 100644
--- a/cpu/arm1176/s3c64xx/Makefile
+++ b/cpu/arm1176/s3c64xx/Makefile
@@ -30,6 +30,7 @@ LIB	= $(obj)lib$(SOC).a
 
 COBJS-y	= interrupts.o
 COBJS-$(CONFIG_S3C6400)	+= cpu_init.o speed.o
+COBJS-$(CONFIG_USB_OHCI_NEW) += usb.o
 
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
 
diff --git a/cpu/arm1176/s3c64xx/usb.c b/cpu/arm1176/s3c64xx/usb.c
new file mode 100644
index 0000000..274a4ed
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/usb.c
@@ -0,0 +1,45 @@
+/*
+ * URB OHCI HCD (Host Controller Driver) initialization for USB on the S3C64XX.
+ *
+ * Copyright (C) 2008,
+ * Guennadi Liakhovetski, DENX Software Engineering <lg@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 <common.h>
+#include <s3c6400.h>
+
+int usb_cpu_init(void)
+{
+	OTHERS_REG |= 0x10000;
+	return 0;
+}
+
+int usb_cpu_stop(void)
+{
+	OTHERS_REG &= ~0x10000;
+	return 0;
+}
+
+void usb_cpu_init_fail(void)
+{
+	OTHERS_REG &= ~0x10000;
+}
diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c
index fd60edb..0bfa4d7 100644
--- a/drivers/usb/usb_ohci.c
+++ b/drivers/usb/usb_ohci.c
@@ -69,6 +69,7 @@
 #if defined(CONFIG_ARM920T) || \
     defined(CONFIG_S3C2400) || \
     defined(CONFIG_S3C2410) || \
+    defined(CONFIG_S3C6400) || \
     defined(CONFIG_440EP) || \
     defined(CONFIG_PCI_OHCI) || \
     defined(CONFIG_MPC5200) || \
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
                             ` (3 preceding siblings ...)
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 4/7 v3] USB: Add support for OHCI controller on s3c6400 Guennadi Liakhovetski
@ 2008-08-04 12:45           ` Guennadi Liakhovetski
  2008-08-04 21:19             ` Jean-Christophe PLAGNIOL-VILLARD
  2008-08-04 12:46           ` [U-Boot-Users] [PATCH 6/7 v3] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
  2008-08-04 12:46           ` [U-Boot-Users] [PATCH 7/7 v3] ARM: Add support for S3C6400 based SMDK6400 board Guennadi Liakhovetski
  6 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:45 UTC (permalink / raw)
  To: u-boot

Ported from u-boot-1.1.6 driver by Samsung.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---

Also added my copyright to the driver.

 drivers/serial/Makefile  |    1 +
 drivers/serial/s3c64xx.c |  189 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 190 insertions(+), 0 deletions(-)
 create mode 100644 drivers/serial/s3c64xx.c

diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index c9e797e..2a11ae5 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -30,6 +30,7 @@ COBJS-y += mcfuart.o
 COBJS-y += ns9750_serial.o
 COBJS-y += ns16550.o
 COBJS-y += s3c4510b_uart.o
+COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
 COBJS-y += serial.o
 COBJS-y += serial_max3100.o
 COBJS-y += serial_pl010.o
diff --git a/drivers/serial/s3c64xx.c b/drivers/serial/s3c64xx.c
new file mode 100644
index 0000000..9580909
--- /dev/null
+++ b/drivers/serial/s3c64xx.c
@@ -0,0 +1,189 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 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 <s3c6400.h>
+
+#ifdef CONFIG_SERIAL1
+#define UART_NR	S3C64XX_UART0
+
+#elif defined(CONFIG_SERIAL2)
+#define UART_NR	S3C64XX_UART1
+
+#elif defined(CONFIG_SERIAL3)
+#define UART_NR	S3C64XX_UART2
+
+#else
+#error "Bad: you didn't configure serial ..."
+#endif
+
+#define barrier() asm volatile("" ::: "memory")
+
+/* See table in 31.6.11 */
+static const int udivslot[] = {
+	0,
+	0x0080,
+	0x0808,
+	0x0888,
+	0x2222,
+	0x4924,
+	0x4a52,
+	0x54aa,
+	0x5555,
+	0xd555,
+	0xd5d5,
+	0xddd5,
+	0xdddd,
+	0xdfdd,
+	0xdfdf,
+	0xffdf,
+};
+
+void serial_setbrg(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+	u32 reg, pclk_ratio = get_PCLK() / gd->baudrate;
+	int i;
+
+	/* PCLK / (16 * baudrate) - 1 */
+	reg = pclk_ratio / 16 - 1;
+	i = pclk_ratio - (reg + 1) * 16;
+
+	uart->UBRDIV = reg;
+	uart->UDIVSLOT = udivslot[i];
+
+	for (i = 0; i < 100; i++)
+		barrier();
+}
+
+/*
+ * Initialise the serial port with the given baudrate. The settings
+ * are always 8 data bits, no parity, 1 stop bit, no start bits.
+ *
+ */
+int serial_init(void)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+	/* reset and enable FIFOs, set triggers to the maximum */
+	uart->UFCON = 0xff;
+	uart->UMCON = 0;
+	/* 8N1 */
+	uart->ULCON = 3;
+	/* No interrupts, no DMA, pure polling */
+	uart->UCON = 5;
+
+	serial_setbrg();
+
+	return 0;
+}
+
+/*
+ * Read a single byte from the serial port. Returns 1 on success, 0
+ * otherwise. When the function is succesfull, the character read is
+ * written into its argument c.
+ */
+int serial_getc(void)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+	/* wait for character to arrive */
+	while (!(uart->UTRSTAT & 0x1));
+
+	return uart->URXH & 0xff;
+}
+
+#ifdef CONFIG_HWFLOW
+static int hwflow;		/* turned off by default */
+int hwflow_onoff(int on)
+{
+	switch (on) {
+	case 1:
+		hwflow = 1;	/* turn on */
+		break;
+	case -1:
+		hwflow = 0;	/* turn off */
+		break;
+	}
+	return hwflow;
+}
+#endif
+
+#ifdef CONFIG_MODEM_SUPPORT
+static int be_quiet;
+void disable_putc(void)
+{
+	be_quiet = 1;
+}
+
+void enable_putc(void)
+{
+	be_quiet = 0;
+}
+#endif
+
+
+/*
+ * Output a single byte to the serial port.
+ */
+void serial_putc(const char c)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+#ifdef CONFIG_MODEM_SUPPORT
+	if (be_quiet)
+		return;
+#endif
+
+	/* wait for room in the tx FIFO */
+	while (!(uart->UTRSTAT & 0x2));
+
+#ifdef CONFIG_HWFLOW
+	/* Wait for CTS up */
+	while (hwflow && !(uart->UMSTAT & 0x1));
+#endif
+
+	uart->UTXH = c;
+
+	/* If \n, also do \r */
+	if (c == '\n')
+		serial_putc('\r');
+}
+
+/*
+ * Test whether a character is in the RX buffer
+ */
+int serial_tstc(void)
+{
+	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
+
+	return uart->UTRSTAT & 0x1;
+}
+
+void serial_puts(const char *s)
+{
+	while (*s)
+		serial_putc(*s++);
+}
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 6/7 v3] NAND: add NAND driver for s3c64xx
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
                             ` (4 preceding siblings ...)
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver Guennadi Liakhovetski
@ 2008-08-04 12:46           ` Guennadi Liakhovetski
  2008-08-04 22:38             ` Scott Wood
  2008-08-04 12:46           ` [U-Boot-Users] [PATCH 7/7 v3] ARM: Add support for S3C6400 based SMDK6400 board Guennadi Liakhovetski
  6 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:46 UTC (permalink / raw)
  To: u-boot

Ported from u-boot-1.1.6 driver by Samsung.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 drivers/mtd/nand/Makefile  |    1 +
 drivers/mtd/nand/s3c64xx.c |  307 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 308 insertions(+), 0 deletions(-)
 create mode 100644 drivers/mtd/nand/s3c64xx.c

diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 7bd22a0..236cf03 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -33,6 +33,7 @@ COBJS-y += nand_bbt.o
 COBJS-y += nand_util.o
 
 COBJS-y += fsl_upm.o
+COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c
new file mode 100644
index 0000000..162ec26
--- /dev/null
+++ b/drivers/mtd/nand/s3c64xx.c
@@ -0,0 +1,307 @@
+/*
+ * (C) Copyright 2006 DENX Software Engineering
+ *
+ * Implementation for U-Boot 1.1.6 by Samsung
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
+
+#include <nand.h>
+#include <s3c6400.h>
+
+#include <asm/io.h>
+
+#ifdef CONFIG_NAND_SPL
+#define printf(arg...) do {} while (0)
+#endif
+
+/* Nand flash definition values by jsgood */
+#ifdef S3C_NAND_DEBUG
+/*
+ * Function to print out oob buffer for debugging
+ * Written by jsgood
+ */
+static void print_oob(const char *header, struct mtd_info *mtd)
+{
+	int i;
+	struct nand_chip *chip = mtd->priv;
+
+	printf("%s:\t", header);
+
+	for (i = 0; i < 64; i++)
+		printf("%02x ", chip->oob_poi[i]);
+
+	printf("\n");
+}
+#endif /* S3C_NAND_DEBUG */
+
+#ifdef CONFIG_NAND_SPL
+static u_char nand_read_byte(struct mtd_info *mtd)
+{
+	struct nand_chip *this = mtd->priv;
+	return readb(this->IO_ADDR_R);
+}
+
+static void nand_write_byte(struct mtd_info *mtd, u_char byte)
+{
+	struct nand_chip *this = mtd->priv;
+	writeb(byte, this->IO_ADDR_W);
+}
+
+static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
+{
+	int i;
+	struct nand_chip *this = mtd->priv;
+
+	for (i = 0; i < len; i++)
+		buf[i] = readb(this->IO_ADDR_R);
+}
+#endif
+
+static void s3c_nand_select_chip(struct mtd_info *mtd, int chip)
+{
+	int ctrl = readl(NFCONT);
+
+	switch (chip) {
+	case -1:
+		ctrl |= 6;
+		break;
+	case 0:
+		ctrl &= ~2;
+		break;
+	case 1:
+		ctrl &= ~4;
+		break;
+	default:
+		return;
+	}
+
+	writel(ctrl, NFCONT);
+}
+
+/*
+ * Hardware specific access to control-lines function
+ * Written by jsgood
+ */
+static void s3c_nand_hwcontrol(struct mtd_info *mtd, int cmd)
+{
+	struct nand_chip *this = mtd->priv;
+
+	switch (cmd) {
+	case NAND_CTL_SETCLE:
+		this->IO_ADDR_W = (void __iomem *)NFCMMD;
+		break;
+	case NAND_CTL_CLRCLE:
+		this->IO_ADDR_W = (void __iomem *)NFDATA;
+		break;
+	case NAND_CTL_SETALE:
+		this->IO_ADDR_W = (void __iomem *)NFADDR;
+		break;
+	case NAND_CTL_CLRALE:
+		this->IO_ADDR_W = (void __iomem *)NFDATA;
+		break;
+	case NAND_CTL_SETNCE:
+		s3c_nand_select_chip(mtd, 0);
+		break;
+	case NAND_CTL_CLRNCE:
+		s3c_nand_select_chip(mtd, -1);
+		break;
+	}
+}
+
+/*
+ * Function for checking device ready pin
+ * Written by jsgood
+ */
+static int s3c_nand_device_ready(struct mtd_info *mtdinfo)
+{
+	while (!(readl(NFSTAT) & NFSTAT_RnB)) {}
+	return 1;
+}
+
+#ifdef CFG_S3C_NAND_HWECC
+/*
+ * This function is called before encoding ecc codes to ready ecc engine.
+ * Written by jsgood
+ */
+static void s3c_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+	u_long nfcont, nfconf;
+
+	/*
+	 * The original driver used 4-bit ECC for "new" MLC chips, i.e., for
+	 * those with non-zero ID[3][3:2], which anyway only holds for ST
+	 * (Numonyx) chips
+	 */
+	nfconf = readl(NFCONF) & ~NFCONF_ECC_4BIT;
+
+	writel(nfconf, NFCONF);
+
+	/* Initialize & unlock */
+	nfcont = readl(NFCONT);
+	nfcont |= NFCONT_INITECC;
+	nfcont &= ~NFCONT_MECCLOCK;
+
+	if (mode == NAND_ECC_WRITE)
+		nfcont |= NFCONT_ECC_ENC;
+	else if (mode == NAND_ECC_READ)
+		nfcont &= ~NFCONT_ECC_ENC;
+
+	writel(nfcont, NFCONT);
+}
+
+/*
+ * This function is called immediately after encoding ecc codes.
+ * This function returns encoded ecc codes.
+ * Written by jsgood
+ */
+static int s3c_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+				  u_char *ecc_code)
+{
+	u_long nfcont, nfmecc0;
+
+	/* Lock */
+	nfcont = readl(NFCONT);
+	nfcont |= NFCONT_MECCLOCK;
+	writel(nfcont, NFCONT);
+
+	nfmecc0 = readl(NFMECC0);
+
+	ecc_code[0] = nfmecc0 & 0xff;
+	ecc_code[1] = (nfmecc0 >> 8) & 0xff;
+	ecc_code[2] = (nfmecc0 >> 16) & 0xff;
+	ecc_code[3] = (nfmecc0 >> 24) & 0xff;
+
+	return 0;
+}
+
+/*
+ * This function determines whether read data is good or not.
+ * If SLC, must write ecc codes to controller before reading status bit.
+ * If MLC, status bit is already set, so only reading is needed.
+ * If status bit is good, return 0.
+ * If correctable errors occured, do that.
+ * If uncorrectable errors occured, return -1.
+ * Written by jsgood
+ */
+static int s3c_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+				 u_char *read_ecc, u_char *calc_ecc)
+{
+	int ret = -1;
+	u_long nfestat0, nfmeccdata0, nfmeccdata1, err_byte_addr;
+	u_char err_type, repared;
+
+	/* SLC: Write ecc to compare */
+	nfmeccdata0 = (calc_ecc[1] << 16) | calc_ecc[0];
+	nfmeccdata1 = (calc_ecc[3] << 16) | calc_ecc[2];
+	writel(nfmeccdata0, NFMECCDATA0);
+	writel(nfmeccdata1, NFMECCDATA1);
+
+	/* Read ecc status */
+	nfestat0 = readl(NFESTAT0);
+	err_type = nfestat0 & 0x3;
+
+	switch (err_type) {
+	case 0: /* No error */
+		ret = 0;
+		break;
+
+	case 1:
+		/*
+		 * 1 bit error (Correctable)
+		 * (nfestat0 >> 7) & 0x7ff	:error byte number
+		 * (nfestat0 >> 4) & 0x7	:error bit number
+		 */
+		err_byte_addr = (nfestat0 >> 7) & 0x7ff;
+		repared = dat[err_byte_addr] ^ (1 << ((nfestat0 >> 4) & 0x7));
+
+		printf("S3C NAND: 1 bit error detected at byte %ld. "
+		       "Correcting from 0x%02x to 0x%02x...OK\n",
+		       err_byte_addr, dat[err_byte_addr], repared);
+
+		dat[err_byte_addr] = repared;
+
+		ret = 1;
+		break;
+
+	case 2: /* Multiple error */
+	case 3: /* ECC area error */
+		printf("S3C NAND: ECC uncorrectable error detected. "
+		       "Not correctable.\n");
+		ret = -1;
+		break;
+	}
+
+	return ret;
+}
+#endif /* CFG_S3C_NAND_HWECC */
+
+/*
+ * Board-specific NAND initialization. The following members of the
+ * argument are board-specific (per include/linux/mtd/nand.h):
+ * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
+ * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
+ * - hwcontrol: hardwarespecific function for accesing control-lines
+ * - dev_ready: hardwarespecific function for  accesing device ready/busy line
+ * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must
+ *   only be provided if a hardware ECC is available
+ * - eccmode: mode of ecc, see defines
+ * - chip_delay: chip dependent delay for transfering data from array to
+ *   read regs (tR)
+ * - options: various chip options. They can partly be set to inform
+ *   nand_scan about special functionality. See the defines for further
+ *   explanation
+ * Members with a "?" were not set in the merged testing-NAND branch,
+ * so they are not set here either.
+ */
+int board_nand_init(struct nand_chip *nand)
+{
+	NFCONT_REG = (NFCONT_REG & ~NFCONT_WP) | NFCONT_ENABLE | 0x6;
+
+	nand->IO_ADDR_R		= (void __iomem *)NFDATA;
+	nand->IO_ADDR_W		= (void __iomem *)NFDATA;
+	nand->hwcontrol		= s3c_nand_hwcontrol;
+	nand->dev_ready		= s3c_nand_device_ready;
+	nand->select_chip	= s3c_nand_select_chip;
+	nand->options		= 0;
+#ifdef CONFIG_NAND_SPL
+	nand->read_byte		= nand_read_byte;
+	nand->write_byte	= nand_write_byte;
+	nand->read_buf		= nand_read_buf;
+#endif
+
+#ifdef CFG_S3C_NAND_HWECC
+	nand->enable_hwecc	= s3c_nand_enable_hwecc;
+	nand->calculate_ecc	= s3c_nand_calculate_ecc;
+	nand->correct_data	= s3c_nand_correct_data;
+
+	/* A shot in the dark, I don't know how to use this smart ECC-mode
+	 * selection with the current driver */
+	nand->eccmode		= NAND_ECC_HW12_2048;
+#else
+	nand->eccmode		= NAND_ECC_SOFT;
+#endif /* ! CFG_S3C_NAND_HWECC */
+
+	return 0;
+}
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 7/7 v3] ARM: Add support for S3C6400 based SMDK6400 board
  2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
                             ` (5 preceding siblings ...)
  2008-08-04 12:46           ` [U-Boot-Users] [PATCH 6/7 v3] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
@ 2008-08-04 12:46           ` Guennadi Liakhovetski
  2008-08-04 20:10             ` Guennadi Liakhovetski
  6 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 12:46 UTC (permalink / raw)
  To: u-boot

SMDK6400 can only boot U-Boot from NAND-flash. This patch adds a nand_spl
driver for it too. The board can also boot from the NOR flash, but due to
hardware limitations it can only address 64KiB on it, which is not enough
for U-Boot. Ported from u-boot-1.1.6 version by Samsung.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---
 MAKEALL                                    |    1 +
 Makefile                                   |   17 ++
 board/samsung/smdk6400/Makefile            |   54 +++++
 board/samsung/smdk6400/config.mk           |   30 +++
 board/samsung/smdk6400/lowlevel_init.S     |  316 ++++++++++++++++++++++++++++
 board/samsung/smdk6400/smdk6400.c          |  130 ++++++++++++
 board/samsung/smdk6400/u-boot-nand.lds     |   62 ++++++
 include/configs/smdk6400.h                 |  304 ++++++++++++++++++++++++++
 nand_spl/board/samsung/smdk6400/Makefile   |  106 ++++++++++
 nand_spl/board/samsung/smdk6400/config.mk  |   40 ++++
 nand_spl/board/samsung/smdk6400/u-boot.lds |   61 ++++++
 11 files changed, 1121 insertions(+), 0 deletions(-)
 create mode 100644 board/samsung/smdk6400/Makefile
 create mode 100644 board/samsung/smdk6400/config.mk
 create mode 100644 board/samsung/smdk6400/lowlevel_init.S
 create mode 100644 board/samsung/smdk6400/smdk6400.c
 create mode 100644 board/samsung/smdk6400/u-boot-nand.lds
 create mode 100644 include/configs/smdk6400.h
 create mode 100644 nand_spl/board/samsung/smdk6400/Makefile
 create mode 100644 nand_spl/board/samsung/smdk6400/config.mk
 create mode 100644 nand_spl/board/samsung/smdk6400/u-boot.lds

diff --git a/MAKEALL b/MAKEALL
index ee83cca..a3ed47d 100755
--- a/MAKEALL
+++ b/MAKEALL
@@ -515,6 +515,7 @@ LIST_ARM11="		\
 	imx31_litekit	\
 	imx31_phycore	\
 	mx31ads		\
+	smdk6400	\
 "
 
 #########################################################################
diff --git a/Makefile b/Makefile
index b104617..0c5b8a6 100644
--- a/Makefile
+++ b/Makefile
@@ -2677,6 +2677,23 @@ mx31ads_config		: unconfig
 omap2420h4_config	: unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4 NULL omap24xx
 
+#########################################################################
+## ARM1176 Systems
+#########################################################################
+smdk6400_noUSB_config	\
+smdk6400_config	:	unconfig
+	@mkdir -p $(obj)include $(obj)board/samsung/smdk6400
+	@mkdir -p $(obj)nand_spl/board/samsung/smdk6400
+	@echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
+	@if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then			\
+		echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
+		$(MKCONFIG) $(@:_config=) arm arm1176 smdk6400 samsung s3c64xx;		\
+	else										\
+		echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
+		$(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6400 samsung s3c64xx;	\
+	fi
+	@echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk
+
 #========================================================================
 # i386
 #========================================================================
diff --git a/board/samsung/smdk6400/Makefile b/board/samsung/smdk6400/Makefile
new file mode 100644
index 0000000..d35dc8b
--- /dev/null
+++ b/board/samsung/smdk6400/Makefile
@@ -0,0 +1,54 @@
+#
+# (C) Copyright 2000, 2001, 2002
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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	:= smdk6400.o
+SOBJS	:= lowlevel_init.o
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(AR) crv $@ $(OBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+#.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+#		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/samsung/smdk6400/config.mk b/board/samsung/smdk6400/config.mk
new file mode 100644
index 0000000..298d387
--- /dev/null
+++ b/board/samsung/smdk6400/config.mk
@@ -0,0 +1,30 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+#
+# SAMSUNG SMDK6400 board with mDirac3 (ARM1176) cpu
+#
+# see http://www.samsung.com/ for more information on SAMSUNG
+
+# On SMDK6400 we use the 64 MB SDRAM bank at
+#
+# 0x50000000 to 0x58000000
+#
+# Linux-Kernel is expected to be at 0x50008000, entry 0x50008000
+#
+# we load ourselves to 0x57e00000 without MMU
+# with MMU, load address is changed to 0xc7e00000
+#
+# download area is 0x5000c000
+
+sinclude $(OBJTREE)/board/$(BOARDDIR)/config.tmp
+
+ifndef CONFIG_NAND_SPL
+TEXT_BASE = $(RAM_TEXT)
+else
+TEXT_BASE = 0
+endif
diff --git a/board/samsung/smdk6400/lowlevel_init.S b/board/samsung/smdk6400/lowlevel_init.S
new file mode 100644
index 0000000..034c810
--- /dev/null
+++ b/board/samsung/smdk6400/lowlevel_init.S
@@ -0,0 +1,316 @@
+/*
+ * 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@elsoft.ch>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <config.h>
+#include <version.h>
+
+#include <s3c6400.h>
+
+#ifdef CONFIG_SERIAL1
+#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART0_OFFSET)
+#elif defined(CONFIG_SERIAL2)
+#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART1_OFFSET)
+#else
+#define ELFIN_UART_CONSOLE_BASE (ELFIN_UART_BASE + ELFIN_UART2_OFFSET)
+#endif
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+	.globl lowlevel_init
+lowlevel_init:
+	mov	r12, lr
+
+	/* LED on only #8 */
+	ldr	r0, =ELFIN_GPIO_BASE
+	ldr	r1, =0x55540000
+	str	r1, [r0, #GPNCON_OFFSET]
+
+	ldr	r1, =0x55555555
+	str	r1, [r0, #GPNPUD_OFFSET]
+
+	ldr	r1, =0xf000
+	str	r1, [r0, #GPNDAT_OFFSET]
+
+	/* Disable Watchdog */
+	ldr	r0, =0x7e000000		@0x7e004000
+	orr	r0, r0, #0x4000
+	mov	r1, #0
+	str	r1, [r0]
+
+	/* External interrupt pending clear */
+	ldr	r0, =(ELFIN_GPIO_BASE+EINTPEND_OFFSET)	/*EINTPEND*/
+	ldr	r1, [r0]
+	str	r1, [r0]
+
+	ldr	r0, =ELFIN_VIC0_BASE_ADDR 	@0x71200000
+	ldr	r1, =ELFIN_VIC1_BASE_ADDR 	@0x71300000
+
+	/* Disable all interrupts (VIC0 and VIC1) */
+	mvn	r3, #0x0
+	str	r3, [r0, #oINTMSK]
+	str	r3, [r1, #oINTMSK]
+
+	/* Set all interrupts as IRQ */
+	mov	r3, #0x0
+	str	r3, [r0, #oINTMOD]
+	str	r3, [r1, #oINTMOD]
+
+	/* Pending Interrupt Clear */
+	mov	r3, #0x0
+	str	r3, [r0, #oVECTADDR]
+	str	r3, [r1, #oVECTADDR]
+
+	/* init system clock */
+	bl system_clock_init
+
+#ifndef CONFIG_NAND_SPL
+	/* for UART */
+	bl uart_asm_init
+#endif
+
+#ifdef CONFIG_BOOT_NAND
+	/* simple init for NAND */
+	bl nand_asm_init
+#endif
+
+	bl	mem_ctrl_asm_init
+
+/* Wakeup support. Don't know if it's going to be used, untested. */
+        ldr     r0, =(ELFIN_CLOCK_POWER_BASE + RST_STAT_OFFSET)
+        ldr     r1, [r0]
+        bic     r1, r1, #0xfffffff7
+        cmp     r1, #0x8
+        beq     wakeup_reset
+
+1:
+	mov	lr, r12
+	mov	pc, lr
+
+wakeup_reset:
+
+	/* Clear wakeup status register */
+	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + WAKEUP_STAT_OFFSET)
+	ldr	r1, [r0]
+	str	r1, [r0]
+
+        /* LED test */
+        ldr     r0, =ELFIN_GPIO_BASE
+        ldr     r1, =0x3000
+        str     r1, [r0, #GPNDAT_OFFSET]
+
+	/* Load return address and jump to kernel */
+	ldr	r0, =(ELFIN_CLOCK_POWER_BASE + INF_REG0_OFFSET)
+	/* r1 = physical address of s3c6400_cpu_resume function */
+	ldr	r1, [r0]
+	/* Jump to kernel (sleep-s3c6400.S) */
+	mov	pc, r1
+	nop
+	nop
+/*
+ * system_clock_init: Initialize core clock and bus clock.
+ * void system_clock_init(void)
+ */
+system_clock_init:
+	ldr	r0, =ELFIN_CLOCK_POWER_BASE	/* 0x7e00f000 */
+
+#ifdef CONFIG_SYNC_MODE
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	mov	r2, #0x40
+	orr	r1, r1, r2
+	str	r1, [r0, #OTHERS_OFFSET]
+
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	ldr	r2, =0x80
+	orr	r1, r1, r2
+	str	r1, [r0, #OTHERS_OFFSET]
+
+check_syncack:
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	ldr	r2, =0xf00
+	and	r1, r1, r2
+	cmp	r1, #0xf00
+	bne	check_syncack
+#else	/* ASYNC Mode */
+	nop
+	nop
+	nop
+	nop
+	nop
+
+	/*
+	 * This was unconditional in original Samsung sources, but it doesn't
+	 * seem to make much sense on S3C6400.
+	 */
+#ifndef CONFIG_S3C6400
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	bic	r1, r1, #0xC0
+	orr	r1, r1, #0x40
+	str	r1, [r0, #OTHERS_OFFSET]
+
+wait_for_async:
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	and	r1, r1, #0xf00
+	cmp	r1, #0x0
+	bne	wait_for_async
+#endif
+
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	bic	r1, r1, #0x40
+	str	r1, [r0, #OTHERS_OFFSET]
+#endif
+
+	mov	r1, #0xff00
+	orr	r1, r1, #0xff
+	str	r1, [r0, #APLL_LOCK_OFFSET]
+	str	r1, [r0, #MPLL_LOCK_OFFSET]
+
+	/* Set Clock Divider */
+	ldr   	r1, [r0, #CLK_DIV0_OFFSET]
+	bic	r1, r1, #0x30000
+	bic	r1, r1, #0xff00
+	bic	r1, r1, #0xff
+	ldr	r2, =CLK_DIV_VAL
+	orr	r1, r1, r2
+	str	r1, [r0, #CLK_DIV0_OFFSET]
+
+	ldr	r1, =APLL_VAL
+	str	r1, [r0, #APLL_CON_OFFSET]
+	ldr	r1, =MPLL_VAL
+	str	r1, [r0, #MPLL_CON_OFFSET]
+
+	/* FOUT of EPLL is 96MHz */
+	ldr	r1, =0x200203
+	str	r1, [r0, #EPLL_CON0_OFFSET]
+	ldr	r1, =0x0
+	str	r1, [r0, #EPLL_CON1_OFFSET]
+
+	/* APLL, MPLL, EPLL select to Fout */
+	ldr	r1, [r0, #CLK_SRC_OFFSET]
+	orr	r1, r1, #0x7
+	str	r1, [r0, #CLK_SRC_OFFSET]
+
+	/* wait at least 200us to stablize all clock */
+	mov	r1, #0x10000
+1:	subs	r1, r1, #1
+	bne	1b
+
+	/* Synchronization for VIC port */
+#if defined(CONFIG_SYNC_MODE)
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	orr	r1, r1, #0x20
+	str	r1, [r0, #OTHERS_OFFSET]
+#elif !defined(CONFIG_S3C6400)
+	/* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
+	ldr	r1, [r0, #OTHERS_OFFSET]
+	bic	r1, r1, #0x20
+	str	r1, [r0, #OTHERS_OFFSET]
+#endif
+	mov	pc, lr
+
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * uart_asm_init: Initialize UART's pins
+ */
+uart_asm_init:
+	/* set GPIO to enable UART */
+	ldr	r0, =ELFIN_GPIO_BASE
+	ldr	r1, =0x220022
+	str   	r1, [r0, #GPACON_OFFSET]
+	mov	pc, lr
+#endif
+
+#ifdef CONFIG_BOOT_NAND
+/*
+ * NAND Interface init for SMDK6400
+ */
+nand_asm_init:
+	ldr	r0, =ELFIN_NAND_BASE
+	ldr	r1, [r0, #NFCONF_OFFSET]
+	orr	r1, r1, #0x70
+	orr	r1, r1, #0x7700
+	str     r1, [r0, #NFCONF_OFFSET]
+
+	ldr	r1, [r0, #NFCONT_OFFSET]
+	orr	r1, r1, #0x07
+	str     r1, [r0, #NFCONT_OFFSET]
+
+	mov	pc, lr
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+/*
+ * MMU Table for SMDK6400
+ */
+
+	/* form a first-level section entry */
+.macro FL_SECTION_ENTRY base,ap,d,c,b
+	.word (\base << 20) | (\ap << 10) | \
+	      (\d << 5) | (1<<4) | (\c << 3) | (\b << 2) | (1<<1)
+.endm
+
+.section .mmudata, "a"
+	.align 14
+	/* the following alignment creates the mmu table@address 0x4000. */
+	.globl mmu_table
+mmu_table:
+	.set __base, 0
+	/* 1:1 mapping for debugging */
+	.rept 0xA00
+	FL_SECTION_ENTRY __base, 3, 0, 0, 0
+	.set __base, __base + 1
+	.endr
+
+	/* access is not allowed. */
+	.rept 0xC00 - 0xA00
+	.word 0x00000000
+	.endr
+
+	/* 128MB for SDRAM 0xC0000000 -> 0x50000000 */
+	.set __base, 0x500
+	.rept 0xC80 - 0xC00
+	FL_SECTION_ENTRY __base, 3, 0, 1, 1
+	.set __base, __base + 1
+	.endr
+
+	/* access is not allowed. */
+	.rept 0x1000 - 0xc80
+	.word 0x00000000
+	.endr
+#endif
diff --git a/board/samsung/smdk6400/smdk6400.c b/board/samsung/smdk6400/smdk6400.c
new file mode 100644
index 0000000..77fd2c8
--- /dev/null
+++ b/board/samsung/smdk6400/smdk6400.c
@@ -0,0 +1,130 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
+#include <s3c6400.h>
+
+/* ------------------------------------------------------------------------- */
+#define CS8900_Tacs	0x0	/* 0clk		address set-up		*/
+#define CS8900_Tcos	0x4	/* 4clk		chip selection set-up	*/
+#define CS8900_Tacc	0xE	/* 14clk	access cycle		*/
+#define CS8900_Tcoh	0x1	/* 1clk		chip selection hold	*/
+#define CS8900_Tah	0x4	/* 4clk		address holding time	*/
+#define CS8900_Tacp	0x6	/* 6clk		page mode access cycle	*/
+#define CS8900_PMC	0x0	/* normal(1data)page mode configuration	*/
+
+static inline void delay(unsigned long loops)
+{
+	__asm__ volatile ("1:\n" "subs %0, %1, #1\n"
+			  "bne 1b"
+			  : "=r" (loops) : "0" (loops));
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+static void cs8900_pre_init(void)
+{
+	SROM_BW_REG &= ~(0xf << 4);
+	SROM_BW_REG |= (1 << 7) | (1 << 6) | (1 << 4);
+	SROM_BC1_REG = ((CS8900_Tacs << 28) + (CS8900_Tcos << 24) +
+			(CS8900_Tacc << 16) + (CS8900_Tcoh << 12) +
+			(CS8900_Tah << 8) + (CS8900_Tacp << 4) + CS8900_PMC);
+}
+
+int board_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	cs8900_pre_init();
+
+	/* NOR-flash in SROM0 */
+
+	/* Enable WAIT */
+	SROM_BW_REG |= 4 | 8 | 1;
+
+	gd->bd->bi_arch_number = MACH_TYPE;
+	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+	return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+	printf("Board:   SMDK6400\n");
+	return 0;
+}
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+ulong virt_to_phy_smdk6400(ulong addr)
+{
+	if ((0xc0000000 <= addr) && (addr < 0xc8000000))
+		return addr - 0xc0000000 + 0x50000000;
+	else
+		printf("do not support this address : %08lx\n", addr);
+
+	return addr;
+}
+#endif
+
+#if defined(CONFIG_CMD_NAND) && defined(CFG_NAND_LEGACY)
+#include <linux/mtd/nand.h>
+extern struct nand_chip nand_dev_desc[CFG_MAX_NAND_DEVICE];
+void nand_init(void)
+{
+	nand_probe(CFG_NAND_BASE);
+	if (nand_dev_desc[0].ChipID != NAND_ChipID_UNKNOWN)
+		print_size(nand_dev_desc[0].totlen, "\n");
+}
+#endif
+
+ulong board_flash_get_legacy (ulong base, int banknum, flash_info_t *info)
+{
+	if (banknum == 0) {	/* non-CFI boot flash */
+		info->portwidth = FLASH_CFI_16BIT;
+		info->chipwidth = FLASH_CFI_BY16;
+		info->interface = FLASH_CFI_X16;
+		return 1;
+	} else
+		return 0;
+}
diff --git a/board/samsung/smdk6400/u-boot-nand.lds b/board/samsung/smdk6400/u-boot-nand.lds
new file mode 100644
index 0000000..132ab21
--- /dev/null
+++ b/board/samsung/smdk6400/u-boot-nand.lds
@@ -0,0 +1,62 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  cpu/arm1176/start.o	(.text)
+	  cpu/arm1176/s3c64xx/cpu_init.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);
+	.mmudata : { *(.mmudata) }
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}
diff --git a/include/configs/smdk6400.h b/include/configs/smdk6400.h
new file mode 100644
index 0000000..b5deaa7
--- /dev/null
+++ b/include/configs/smdk6400.h
@@ -0,0 +1,304 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Gary Jennejohn <gj@denx.de>
+ * David Mueller <d.mueller@elsoft.ch>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * Configuation settings for the SAMSUNG SMDK6400(mDirac-III) 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
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_S3C6400		1	/* in a SAMSUNG S3C6400 SoC     */
+#define CONFIG_S3C64XX		1	/* in a SAMSUNG S3C64XX Family  */
+#define CONFIG_SMDK6400		1	/* on a SAMSUNG SMDK6400 Board  */
+
+#define CFG_SDRAM_BASE	0x50000000
+
+/* input clock of PLL: SMDK6400 has 12MHz input clock */
+#define CONFIG_SYS_CLK_FREQ	12000000
+
+#if !defined(CONFIG_NAND_SPL) && (TEXT_BASE >= 0xc0000000)
+#define CONFIG_ENABLE_MMU
+#endif
+
+#define CONFIG_MEMORY_UPPER_CODE
+
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+
+/*
+ * Architecture magic and machine type
+ */
+#define MACH_TYPE		1270
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+
+/*
+ * Size of malloc() pool
+ */
+#define CFG_MALLOC_LEN		(CFG_ENV_SIZE + 1024 * 1024)
+#define CFG_GBL_DATA_SIZE	128	/* size in bytes for initial data */
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_DRIVER_CS8900	1	/* we have a CS8900 on-board	*/
+#define CS8900_BASE	  	0x18800300
+#define CS8900_BUS16		1 	/* follow the Linux driver	*/
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL1          1	/* we use SERIAL 1 on SMDK6400	*/
+
+#define CFG_HUSH_PARSER			/* use "hush" command parser	*/
+#ifdef CFG_HUSH_PARSER
+#define CFG_PROMPT_HUSH_PS2	"> "
+#endif
+
+#define CONFIG_CMDLINE_EDITING
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE		115200
+
+/***********************************************************
+ * Command definition
+ ***********************************************************/
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_NAND
+#if defined(CONFIG_BOOT_ONENAND)
+#define CONFIG_CMD_ONENAND
+#endif
+#define CONFIG_CMD_PING
+#define CONFIG_CMD_ELF
+
+#define CONFIG_BOOTDELAY	3
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
+#if (CONFIG_COMMANDS & CONFIG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	115200	/* speed to run kgdb serial port */
+#define CONFIG_KGDB_SER_INDEX	1	/* which serial port to use	 */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CFG_LONGHELP				/* undef to save memory	      */
+#define CFG_PROMPT		"SMDK6400 # "	/* Monitor Command Prompt     */
+#define CFG_CBSIZE		256		/* Console I/O Buffer Size    */
+#define CFG_PBSIZE		384		/* Print Buffer Size          */
+#define CFG_MAXARGS		16		/* max number of command args */
+#define CFG_BARGSIZE		CFG_CBSIZE	/* Boot Argument Buffer Size  */
+
+#define CFG_MEMTEST_START	CFG_SDRAM_BASE	/* memtest works on	      */
+#define CFG_MEMTEST_END		(CFG_SDRAM_BASE + 0x7e00000) /* 126MB in DRAM */
+
+#define CFG_LOAD_ADDR		CFG_SDRAM_BASE	/* default load address	*/
+
+#define CFG_HZ			1000
+
+/* valid baudrates */
+#define CFG_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	0x40000		/* regular stack 256KB */
+
+/**********************************
+ Support Clock Settings
+ **********************************
+ Setting	SYNC	ASYNC
+ ----------------------------------
+ 667_133_66	 X	  O
+ 533_133_66	 O	  O
+ 400_133_66	 X	  O
+ 400_100_50	 O	  O
+ **********************************/
+
+/*#define CONFIG_CLK_667_133_66*/
+#define CONFIG_CLK_533_133_66
+/*
+#define CONFIG_CLK_400_100_50
+#define CONFIG_CLK_400_133_66
+#define CONFIG_SYNC_MODE
+*/
+
+/* SMDK6400 has 2 banks of DRAM, but we use only one in U-Boot */
+#define CONFIG_NR_DRAM_BANKS	1
+#define PHYS_SDRAM_1		CFG_SDRAM_BASE	/* SDRAM Bank #1	*/
+#define PHYS_SDRAM_1_SIZE	0x08000000	/* 128 MB in Bank #1	*/
+
+#define CFG_FLASH_BASE		0x10000000
+#define CFG_MONITOR_BASE	0x00000000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CFG_MAX_FLASH_BANKS	1	/* max number of memory banks	*/
+/* AM29LV160B has 35 sectors, AM29LV800B - 19 */
+#define CFG_MAX_FLASH_SECT	40
+
+#define CONFIG_AMD_LV800
+#define CFG_FLASH_CFI		1	/* Use CFI parameters (needed?) */
+/* Use drivers/cfi_flash.c, even though the flash is not CFI-compliant	*/
+#define CFG_FLASH_CFI_DRIVER	1
+#define CFG_FLASH_CFI_WIDTH	FLASH_CFI_16BIT
+#define CONFIG_FLASH_CFI_LEGACY
+#define CFG_FLASH_LEGACY_512Kx16
+
+/* timeout values are in ticks */
+#define CFG_FLASH_ERASE_TOUT	(5 * CFG_HZ) /* Timeout for Flash Erase	*/
+#define CFG_FLASH_WRITE_TOUT	(5 * CFG_HZ) /* Timeout for Flash Write	*/
+
+#define CFG_ENV_SIZE		0x4000	/* Total Size of Environment Sector */
+
+/*
+ * SMDK6400 board specific data
+ */
+
+#define CONFIG_IDENT_STRING	" for SMDK6400"
+
+/* base address for uboot */
+#define CFG_PHY_UBOOT_BASE	(CFG_SDRAM_BASE + 0x07e00000)
+/* total memory available to uboot */
+#define CFG_UBOOT_SIZE		(1024 * 1024)
+
+#ifdef CONFIG_ENABLE_MMU
+#define CFG_MAPPED_RAM_BASE	0xc0000000
+#define CONFIG_BOOTCOMMAND	"nand read 0xc0018000 0x60000 0x1c0000;" \
+				"bootm 0xc0018000"
+#else
+#define CFG_MAPPED_RAM_BASE	CFG_SDRAM_BASE
+#define CONFIG_BOOTCOMMAND	"nand read 0x50018000 0x60000 0x1c0000;" \
+				"bootm 0x50018000"
+#endif
+
+/* NAND U-Boot load and start address */
+#define CFG_UBOOT_BASE		(CFG_MAPPED_RAM_BASE + 0x07e00000)
+
+#define CFG_ENV_OFFSET		0x0040000
+
+/* NAND configuration */
+#define CFG_MAX_NAND_DEVICE	1
+#define CFG_NAND_BASE		0x70200010
+#define NAND_MAX_CHIPS		1
+#define CFG_S3C_NAND_HWECC
+
+#define CFG_NAND_SKIP_BAD_DOT_I	1  /* ".i" read skips bad blocks	      */
+#define CFG_NAND_WP		1
+#define CFG_NAND_YAFFS_WRITE	1  /* support yaffs write		      */
+#define CFG_NAND_BBT_2NDPAGE	1  /* bad-block markers in 1st and 2nd pages  */
+
+#define CFG_NAND_U_BOOT_DST	CFG_PHY_UBOOT_BASE	/* NUB load-addr      */
+#define CFG_NAND_U_BOOT_START	CFG_NAND_U_BOOT_DST	/* NUB start-addr     */
+
+#define CFG_NAND_U_BOOT_OFFS	(4 * 1024)	/* Offset to RAM U-Boot image */
+#define CFG_NAND_U_BOOT_SIZE	(252 * 1024)	/* Size of RAM U-Boot image   */
+
+/* NAND chip page size		*/
+#define CFG_NAND_PAGE_SIZE	2048
+/* NAND chip block size		*/
+#define CFG_NAND_BLOCK_SIZE	(128 * 1024)
+/* NAND chip page per block count  */
+#define CFG_NAND_PAGE_COUNT	64
+/* Location of the bad-block label */
+#define CFG_NAND_BAD_BLOCK_POS	0
+/* Extra address cycle for > 128MiB */
+#define CFG_NAND_5_ADDR_CYCLE
+
+/* Size of the block protected by one OOB (Spare Area in Samsung terminology) */
+#define CFG_NAND_ECCSIZE	2048 /* 512 */
+/* Number of ECC bytes per OOB */
+#define CFG_NAND_ECCBYTES	12 /* 3 */
+/* Number of ECC-blocks per NAND page */
+#define CFG_NAND_ECCSTEPS	(CFG_NAND_PAGE_SIZE / CFG_NAND_ECCSIZE)
+/* Size of a single OOB region */
+#define CFG_NAND_OOBSIZE	64 /* 16 */
+/* Number of ECC bytes per page */
+#define CFG_NAND_ECCTOTAL	(CFG_NAND_ECCBYTES * CFG_NAND_ECCSTEPS)
+/* ECC byte positions */
+#define CFG_NAND_ECCPOS		{8, 9, 10, 24, 25, 26, 40, 41, 42, 56, 57, 58}
+
+/* Boot configuration (define only one of next 3) */
+#define CONFIG_BOOT_NAND
+/* None of these are currently implemented. Left from the original Samsung
+ * version for reference
+#define CONFIG_BOOT_NOR
+#define CONFIG_BOOT_MOVINAND
+#define CONFIG_BOOT_ONENAND
+*/
+
+#define CONFIG_NAND
+#define CONFIG_NAND_S3C64XX
+/* Unimplemented or unsupported. See comment above.
+#define CONFIG_ONENAND
+#define CONFIG_MOVINAND
+*/
+
+/* Settings as above boot configuration */
+#define CFG_ENV_IS_IN_NAND
+#define CONFIG_BOOTARGS		"console=ttySAC,115200"
+#define CONFIG_EXTRA_ENV_SETTINGS "bootargs=" CONFIG_BOOTARGS
+
+#if !defined(CONFIG_ENABLE_MMU)
+#define CONFIG_CMD_USB			1
+#define CONFIG_USB_OHCI_NEW		1
+#define CFG_USB_OHCI_REGS_BASE		0x74300000
+#define CFG_USB_OHCI_SLOT_NAME		"s3c6400"
+#define CFG_USB_OHCI_MAX_ROOT_PORTS	3
+#define CFG_USB_OHCI_CPU_INIT		1
+#define LITTLEENDIAN			1	/* used by usb_ohci.c	*/
+
+#define CONFIG_USB_STORAGE	1
+#endif
+#define CONFIG_DOS_PARTITION	1
+
+#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_ENABLE_MMU)
+# error "usb_ohci.c is currently broken with MMU enabled."
+#endif
+
+#endif	/* __CONFIG_H */
diff --git a/nand_spl/board/samsung/smdk6400/Makefile b/nand_spl/board/samsung/smdk6400/Makefile
new file mode 100644
index 0000000..ae9eb2a
--- /dev/null
+++ b/nand_spl/board/samsung/smdk6400/Makefile
@@ -0,0 +1,106 @@
+#
+# (C) Copyright 2006-2007
+# Stefan Roese, DENX Software Engineering, sr at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+#
+
+CONFIG_NAND_SPL	= y
+
+include $(TOPDIR)/config.mk
+include $(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk
+
+LDSCRIPT= $(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds
+LDFLAGS	= -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
+AFLAGS	+= -DCONFIG_NAND_SPL
+CFLAGS	+= -DCONFIG_NAND_SPL
+
+SOBJS	= start.o cpu_init.o lowlevel_init.o
+COBJS	= nand_boot.o nand_ecc.o s3c64xx.o
+
+SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+__OBJS	:= $(SOBJS) $(COBJS)
+LNDIR	:= $(OBJTREE)/nand_spl/board/$(BOARDDIR)
+
+nandobj	:= $(OBJTREE)/nand_spl/
+
+ALL	= $(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin
+
+all:	$(obj).depend $(ALL)
+
+$(nandobj)u-boot-spl-16k.bin: $(nandobj)u-boot-spl
+	$(OBJCOPY) ${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@
+
+$(nandobj)u-boot-spl.bin:	$(nandobj)u-boot-spl
+	$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+
+$(nandobj)u-boot-spl:	$(OBJS)
+	cd $(LNDIR) && $(LD) $(LDFLAGS) $(__OBJS) \
+		-Map $(nandobj)u-boot-spl.map \
+		-o $(nandobj)u-boot-spl
+
+# create symbolic links for common files
+
+# from cpu directory
+$(obj)start.S:
+	@rm -f $@
+	@ln -s $(TOPDIR)/cpu/arm1176/start.S $@
+
+# from SoC directory
+$(obj)cpu_init.S:
+	@rm -f $@
+	@ln -s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@
+
+# from board directory
+$(obj)lowlevel_init.S:
+	@rm -f $@
+	@ln -s $(TOPDIR)/board/samsung/smdk6400/lowlevel_init.S $@
+
+# from nand_spl directory
+$(obj)nand_boot.c:
+	@rm -f $@
+	@ln -s $(TOPDIR)/nand_spl/nand_boot.c $@
+
+# from drivers/mtd/nand directory
+$(obj)nand_ecc.c:
+	@rm -f $@
+	@ln -s $(TOPDIR)/drivers/mtd/nand/nand_ecc.c $@
+
+$(obj)s3c64xx.c:
+	@rm -f $@
+	@ln -s $(TOPDIR)/drivers/mtd/nand/s3c64xx.c $@
+
+#########################################################################
+
+$(obj)%.o:	$(obj)%.S
+	$(CC) $(AFLAGS) -c -o $@ $<
+
+$(obj)%.o:	$(obj)%.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/nand_spl/board/samsung/smdk6400/config.mk b/nand_spl/board/samsung/smdk6400/config.mk
new file mode 100644
index 0000000..4b16230
--- /dev/null
+++ b/nand_spl/board/samsung/smdk6400/config.mk
@@ -0,0 +1,40 @@
+#
+# (C) Copyright 2006
+# Stefan Roese, DENX Software Engineering, sr 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
+#
+#
+# Samsung S3C64xx Reference Platform (smdk6400) board
+
+# TEXT_BASE for SPL:
+#
+# On S3C64xx platforms the SPL is located in SRAM@0.
+#
+# TEXT_BASE = 0
+
+include $(TOPDIR)/board/$(BOARDDIR)/config.mk
+
+# PAD_TO used to generate a 4kByte binary needed for the combined image
+# -> PAD_TO = TEXT_BASE + 4096
+PAD_TO	:= $(shell expr $$[$(TEXT_BASE) + 4096])
+
+ifeq ($(debug),1)
+PLATFORM_CPPFLAGS += -DDEBUG
+endif
diff --git a/nand_spl/board/samsung/smdk6400/u-boot.lds b/nand_spl/board/samsung/smdk6400/u-boot.lds
new file mode 100644
index 0000000..1bf022c
--- /dev/null
+++ b/nand_spl/board/samsung/smdk6400/u-boot.lds
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  start.o	(.text)
+	  cpu_init.o	(.text)
+	  nand_boot.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 : { *(.bss) }
+	_end = .;
+}
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 3/7 v4] ARM: Add arm1176 core with s3c6400 SoC
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 3/7 v3] ARM: Add arm1176 core with s3c6400 SoC Guennadi Liakhovetski
@ 2008-08-04 20:06             ` Guennadi Liakhovetski
  0 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 20:06 UTC (permalink / raw)
  To: u-boot

This is a port of s3c6400 sources by Samsung from u-boot-1.1.6.

Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
---

Sorry, there has been a stupid mistake in v3, please, take this one 
instead.

 cpu/arm1176/Makefile                    |   50 ++
 cpu/arm1176/config.mk                   |   35 ++
 cpu/arm1176/cpu.c                       |  189 +++++++
 cpu/arm1176/s3c64xx/Makefile            |   48 ++
 cpu/arm1176/s3c64xx/config.mk           |   34 ++
 cpu/arm1176/s3c64xx/cpu_init.S          |  142 +++++
 cpu/arm1176/s3c64xx/interrupts.c        |  280 ++++++++++
 cpu/arm1176/s3c64xx/speed.c             |  140 +++++
 cpu/arm1176/start.S                     |  469 ++++++++++++++++
 include/asm-arm/arch-s3c64xx/hardware.h |   63 +++
 include/common.h                        |    3 +-
 include/s3c6400.h                       |  884 +++++++++++++++++++++++++++++++
 include/s3c64x0.h                       |   92 ++++
 13 files changed, 2428 insertions(+), 1 deletions(-)
 create mode 100644 cpu/arm1176/Makefile
 create mode 100644 cpu/arm1176/config.mk
 create mode 100644 cpu/arm1176/cpu.c
 create mode 100644 cpu/arm1176/s3c64xx/Makefile
 create mode 100644 cpu/arm1176/s3c64xx/config.mk
 create mode 100644 cpu/arm1176/s3c64xx/cpu_init.S
 create mode 100644 cpu/arm1176/s3c64xx/interrupts.c
 create mode 100644 cpu/arm1176/s3c64xx/speed.c
 create mode 100644 cpu/arm1176/start.S
 create mode 100644 include/asm-arm/arch-s3c64xx/hardware.h
 create mode 100644 include/s3c6400.h
 create mode 100644 include/s3c64x0.h

diff --git a/cpu/arm1176/Makefile b/cpu/arm1176/Makefile
new file mode 100644
index 0000000..1ca9199
--- /dev/null
+++ b/cpu/arm1176/Makefile
@@ -0,0 +1,50 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@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$(CPU).a
+
+START	= start.o
+COBJS	= cpu.o
+
+SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+START	:= $(addprefix $(obj),$(START))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk
new file mode 100644
index 0000000..5083594
--- /dev/null
+++ b/cpu/arm1176/config.mk
@@ -0,0 +1,35 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@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
+#
+PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
+	-msoft-float
+
+# Make ARMv5 to allow more compilers to work, even though its v6.
+PLATFORM_CPPFLAGS += -march=armv5t
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/cpu.c b/cpu/arm1176/cpu.c
new file mode 100644
index 0000000..a0a9268
--- /dev/null
+++ b/cpu/arm1176/cpu.c
@@ -0,0 +1,189 @@
+/*
+ * (C) Copyright 2004 Texas Insturments
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+/*
+ * CPU specific code
+ */
+
+#include <common.h>
+#include <command.h>
+#include <s3c6400.h>
+
+static void cache_flush (void);
+
+/* read co-processor 15, register #1 (control register) */
+static unsigned long read_p15_c1 (void)
+{
+	unsigned long value;
+
+	__asm__ __volatile__(
+		"mrc	p15, 0, %0, c1, c0, 0   @ read control reg\n"
+		: "=r" (value)
+		:
+		: "memory");
+	return value;
+}
+
+/* write to co-processor 15, register #1 (control register) */
+static void write_p15_c1 (unsigned long value)
+{
+	__asm__ __volatile__(
+		"mcr	p15, 0, %0, c1, c0, 0   @ write it back\n"
+		:
+		: "r" (value)
+		: "memory");
+
+	read_p15_c1();
+}
+
+static void cp_delay (void)
+{
+	volatile int i;
+
+	/* Many OMAP regs need at least 2 nops  */
+	for (i = 0; i < 100; i++)
+		__asm__ __volatile__("nop\n");
+}
+
+/* See also ARM Ref. Man. */
+#define C1_MMU		(1 << 0)	/* mmu off/on */
+#define C1_ALIGN	(1 << 1)	/* alignment faults off/on */
+#define C1_DC		(1 << 2)	/* dcache off/on */
+#define C1_WB		(1 << 3)	/* merging write buffer on/off */
+#define C1_BIG_ENDIAN	(1 << 7)	/* big endian off/on */
+#define C1_SYS_PROT	(1 << 8)	/* system protection */
+#define C1_ROM_PROT	(1 << 9)	/* ROM protection */
+#define C1_IC		(1 << 12)	/* icache off/on */
+#define C1_HIGH_VECTORS	(1 << 13)	/* location of vectors: low/high */
+#define RESERVED_1	(0xf << 3)	/* must be 111b for R/W */
+
+int cpu_init (void)
+{
+	return 0;
+}
+
+int cleanup_before_linux (void)
+{
+	/*
+	 * this function is called just before we call linux
+	 * it prepares the processor for linux
+	 *
+	 * we turn off caches etc ...
+	 */
+
+	disable_interrupts ();
+
+	/* turn off I/D-cache */
+	icache_disable();
+	dcache_disable();
+	cache_flush();
+
+	return 0;
+}
+
+
+/* * reset the cpu by setting up the watchdog timer and let him time out */
+void reset_cpu (ulong ignored)
+{
+	printf("reset... \n\n\n");
+	SW_RST_REG = 0x6400;
+	/* loop forever and wait for reset to happen */
+	while (1) {
+		if (serial_tstc()) {
+			serial_getc();
+			break;
+		}
+	}
+	/*NOTREACHED*/
+}
+
+int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+	disable_interrupts ();
+	reset_cpu (0);
+	/*NOTREACHED*/
+	return 0;
+}
+
+void icache_enable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();	/* get control reg. */
+	cp_delay ();
+	write_p15_c1 (reg | C1_IC);
+}
+
+void icache_disable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	write_p15_c1 (reg & ~C1_IC);
+}
+
+int icache_status (void)
+{
+	return (read_p15_c1 () & C1_IC) != 0;
+}
+
+/* It makes no sense to use the dcache if the MMU is not enabled */
+void dcache_enable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	write_p15_c1 (reg | C1_DC);
+}
+
+void dcache_disable (void)
+{
+	ulong reg;
+
+	reg = read_p15_c1 ();
+	cp_delay ();
+	reg &= ~C1_DC;
+	write_p15_c1 (reg);
+}
+
+int dcache_status (void)
+{
+	return (read_p15_c1 () & C1_DC) != 0;
+}
+
+/* flush I/D-cache */
+static void cache_flush (void)
+{
+	/* invalidate both caches and flush btb */
+	asm ("mcr p15, 0, %0, c7, c7, 0": :"r" (0));
+	/* mem barrier to sync things */
+	asm ("mcr p15, 0, %0, c7, c10, 4": :"r" (0));
+}
diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile
new file mode 100644
index 0000000..fa4ee3f
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/Makefile
@@ -0,0 +1,48 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# (C) Copyright 2008
+# Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).a
+
+COBJS-y	= interrupts.o
+COBJS-$(CONFIG_S3C6400)	+= cpu_init.o speed.o
+
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
+
+all:	$(obj).depend $(START) $(LIB)
+
+$(LIB):	$(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk
new file mode 100644
index 0000000..204e880
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/config.mk
@@ -0,0 +1,34 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <gj@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
+#
+PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8 \
+	-msoft-float
+
+# Make ARMv5 to allow more compilers to work, even though its v6.
+PLATFORM_CPPFLAGS += -march=armv5t
+# =========================================================================
+#
+# Supply options according to compiler version
+#
+# =========================================================================
+#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
+PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,))
diff --git a/cpu/arm1176/s3c64xx/cpu_init.S b/cpu/arm1176/s3c64xx/cpu_init.S
new file mode 100644
index 0000000..08bda99
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/cpu_init.S
@@ -0,0 +1,142 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <config.h>
+#include <s3c6400.h>
+
+	.globl mem_ctrl_asm_init
+mem_ctrl_asm_init:
+	/* Memory subsystem address 0x7e00f120 */
+	ldr	r0, =ELFIN_MEM_SYS_CFG
+
+	/* Xm0CSn2 = NFCON CS0, Xm0CSn3 = NFCON CS1 */
+	mov	r1, #0xd
+	str	r1, [r0]
+
+	/* DMC1 base address 0x7e001000 */
+	ldr	r0, =ELFIN_DMC1_BASE
+
+	ldr	r1, =0x4
+	str	r1, [r0, #INDEX_DMC_MEMC_CMD]
+
+	ldr	r1, =DMC_DDR_REFRESH_PRD
+	str	r1, [r0, #INDEX_DMC_REFRESH_PRD]
+
+	ldr	r1, =DMC_DDR_CAS_LATENCY
+	str	r1, [r0, #INDEX_DMC_CAS_LATENCY]
+
+	ldr	r1, =DMC_DDR_t_DQSS
+	str	r1, [r0, #INDEX_DMC_T_DQSS]
+
+	ldr	r1, =DMC_DDR_t_MRD
+	str	r1, [r0, #INDEX_DMC_T_MRD]
+
+	ldr	r1, =DMC_DDR_t_RAS
+	str	r1, [r0, #INDEX_DMC_T_RAS]
+
+	ldr	r1, =DMC_DDR_t_RC
+	str	r1, [r0, #INDEX_DMC_T_RC]
+
+	ldr	r1, =DMC_DDR_t_RCD
+	ldr	r2, =DMC_DDR_schedule_RCD
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RCD]
+
+	ldr	r1, =DMC_DDR_t_RFC
+	ldr	r2, =DMC_DDR_schedule_RFC
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RFC]
+
+	ldr	r1, =DMC_DDR_t_RP
+	ldr	r2, =DMC_DDR_schedule_RP
+	orr	r1, r1, r2
+	str	r1, [r0, #INDEX_DMC_T_RP]
+
+	ldr	r1, =DMC_DDR_t_RRD
+	str	r1, [r0, #INDEX_DMC_T_RRD]
+
+	ldr	r1, =DMC_DDR_t_WR
+	str	r1, [r0, #INDEX_DMC_T_WR]
+
+	ldr	r1, =DMC_DDR_t_WTR
+	str	r1, [r0, #INDEX_DMC_T_WTR]
+
+	ldr	r1, =DMC_DDR_t_XP
+	str	r1, [r0, #INDEX_DMC_T_XP]
+
+	ldr	r1, =DMC_DDR_t_XSR
+	str	r1, [r0, #INDEX_DMC_T_XSR]
+
+	ldr	r1, =DMC_DDR_t_ESR
+	str	r1, [r0, #INDEX_DMC_T_ESR]
+
+	ldr	r1, =DMC1_MEM_CFG
+	str	r1, [r0, #INDEX_DMC_MEMORY_CFG]
+
+	ldr	r1, =DMC1_MEM_CFG2
+	str	r1, [r0, #INDEX_DMC_MEMORY_CFG2]
+
+	ldr	r1, =DMC1_CHIP0_CFG
+	str	r1, [r0, #INDEX_DMC_CHIP_0_CFG]
+
+	ldr	r1, =DMC_DDR_32_CFG
+	str	r1, [r0, #INDEX_DMC_USER_CONFIG]
+
+	/* DMC0 DDR Chip 0 configuration direct command reg */
+	ldr	r1, =DMC_NOP0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Precharge All */
+	ldr	r1, =DMC_PA0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Auto Refresh 2 time */
+	ldr	r1, =DMC_AR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* MRS */
+	ldr	r1, =DMC_mDDR_EMR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Mode Reg */
+	ldr	r1, =DMC_mDDR_MR0
+	str	r1, [r0, #INDEX_DMC_DIRECT_CMD]
+
+	/* Enable DMC1 */
+	mov	r1, #0x0
+	str	r1, [r0, #INDEX_DMC_MEMC_CMD]
+
+check_dmc1_ready:
+	ldr	r1, [r0, #INDEX_DMC_MEMC_STATUS]
+	mov	r2, #0x3
+	and	r1, r1, r2
+	cmp	r1, #0x1
+	bne	check_dmc1_ready
+	nop
+
+	mov	pc, lr
+
+	.ltorg
diff --git a/cpu/arm1176/s3c64xx/interrupts.c b/cpu/arm1176/s3c64xx/interrupts.c
new file mode 100644
index 0000000..4233e8c
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/interrupts.c
@@ -0,0 +1,280 @@
+/*
+ * (C) Copyright 2003
+ * Texas Instruments <www.ti.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * (C) Copyright 2002-2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
+ *
+ * (C) Copyright 2004
+ * Philippe Robin, ARM Ltd. <philippe.robin@arm.com>
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <common.h>
+#include <asm/proc-armv/ptrace.h>
+#include <s3c6400.h>
+
+static ulong timer_load_val;
+
+#define PRESCALER	167
+
+static s3c64xx_timers *s3c64xx_get_base_timers(void)
+{
+	return (s3c64xx_timers *)ELFIN_TIMER_BASE;
+}
+
+/* macro to read the 16 bit timer */
+static inline ulong read_timer(void)
+{
+	s3c64xx_timers *const timers = s3c64xx_get_base_timers();
+
+	return timers->TCNTO4;
+}
+
+/* Internal tick units */
+/* Last decremneter snapshot */
+static unsigned long lastdec;
+/* Monotonic incrementing timer */
+static unsigned long long timestamp;
+
+void enable_interrupts(void)
+{
+	return;
+}
+int disable_interrupts(void)
+{
+	return 0;
+}
+
+void bad_mode(void)
+{
+	panic("Resetting CPU ...\n");
+	reset_cpu(0);
+}
+
+void show_regs(struct pt_regs *regs)
+{
+	unsigned long flags;
+	const char *processor_modes[] = {
+		"USER_26", "FIQ_26", "IRQ_26", "SVC_26",
+		"UK4_26", "UK5_26", "UK6_26", "UK7_26",
+		"UK8_26", "UK9_26", "UK10_26", "UK11_26",
+		"UK12_26", "UK13_26", "UK14_26", "UK15_26",
+		"USER_32", "FIQ_32", "IRQ_32", "SVC_32",
+		"UK4_32", "UK5_32", "UK6_32", "ABT_32",
+		"UK8_32", "UK9_32", "UK10_32", "UND_32",
+		"UK12_32", "UK13_32", "UK14_32", "SYS_32",
+	};
+
+	flags = condition_codes(regs);
+
+	printf("pc : [<%08lx>]	   lr : [<%08lx>]\n"
+	       "sp : %08lx  ip : %08lx	 fp : %08lx\n",
+	       instruction_pointer(regs), regs->ARM_lr, regs->ARM_sp,
+	       regs->ARM_ip, regs->ARM_fp);
+	printf("r10: %08lx  r9 : %08lx	 r8 : %08lx\n", regs->ARM_r10,
+	       regs->ARM_r9, regs->ARM_r8);
+	printf("r7 : %08lx  r6 : %08lx	 r5 : %08lx  r4 : %08lx\n",
+	       regs->ARM_r7, regs->ARM_r6, regs->ARM_r5, regs->ARM_r4);
+	printf("r3 : %08lx  r2 : %08lx	 r1 : %08lx  r0 : %08lx\n",
+	       regs->ARM_r3, regs->ARM_r2, regs->ARM_r1, regs->ARM_r0);
+	printf("Flags: %c%c%c%c",
+	       flags & CC_N_BIT ? 'N' : 'n',
+	       flags & CC_Z_BIT ? 'Z' : 'z',
+	       flags & CC_C_BIT ? 'C' : 'c', flags & CC_V_BIT ? 'V' : 'v');
+	printf("  IRQs %s  FIQs %s  Mode %s%s\n",
+	       interrupts_enabled(regs) ? "on" : "off",
+	       fast_interrupts_enabled(regs) ? "on" : "off",
+	       processor_modes[processor_mode(regs)], thumb_mode(regs) ?
+	       " (T)" : "");
+}
+
+void do_undefined_instruction(struct pt_regs *pt_regs)
+{
+	printf("undefined instruction\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_software_interrupt(struct pt_regs *pt_regs)
+{
+	printf("software interrupt\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_prefetch_abort(struct pt_regs *pt_regs)
+{
+	printf("prefetch abort\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_data_abort(struct pt_regs *pt_regs)
+{
+	printf("data abort\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_not_used(struct pt_regs *pt_regs)
+{
+	printf("not used\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_fiq(struct pt_regs *pt_regs)
+{
+	printf("fast interrupt request\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+void do_irq(struct pt_regs *pt_regs)
+{
+	printf("interrupt request\n");
+	show_regs(pt_regs);
+	bad_mode();
+}
+
+int interrupt_init(void)
+{
+	s3c64xx_timers *const timers = s3c64xx_get_base_timers();
+
+	/* use PWM Timer 4 because it has no output */
+	/*
+	 * We use the following scheme for the timer:
+	 * Prescaler is hard fixed at 167, divider at 1/4.
+	 * This gives at PCLK frequency 66MHz approx. 10us ticks
+	 * The timer is set to wrap after 100s, at 66MHz this obviously
+	 * happens after 10,000,000 ticks. A long variable can thus
+	 * keep values up to 40,000s, i.e., 11 hours. This should be
+	 * enough for most uses:-) Possible optimizations: select a
+	 * binary-friendly frequency, e.g., 1ms / 128. Also calculate
+	 * the prescaler automatically for other PCLK frequencies.
+	 */
+	/* Set timer frequency to 500KHz, at 66MHz we get prescaler=132 < 255 */
+	timers->TCFG0 = PRESCALER << 8;
+	if (timer_load_val == 0) {
+		/*
+		 * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 and
+		 * prescaler = 16. Should be 10390 @33.25MHz and 15625 @ 50 MHz
+		 */
+		timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */
+		/*printf("Calculated %lu timer_load_val\n", timer_load_val);*/
+		timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000;
+	}
+
+	/* load value for 10 ms timeout */
+	lastdec = timers->TCNTB4 = timer_load_val;
+	/* auto load, manual update of Timer 4 */
+	timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO |
+		TCON_4_UPDATE;
+	/* auto load, start Timer 4 */
+	timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON;
+	timestamp = 0;
+
+	return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	ulong now = read_timer();
+
+	if (lastdec >= now) {
+		/* normal mode */
+		timestamp += lastdec - now;
+	} else {
+		/* we have an overflow ... */
+		timestamp += lastdec + timer_load_val - now;
+	}
+	lastdec = now;
+
+	return timestamp;
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	/* We overrun in 100s */
+	return (ulong)(timer_load_val / 100);
+}
+
+void reset_timer_masked(void)
+{
+	/* reset time */
+	lastdec = read_timer();
+	timestamp = 0;
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+ulong get_timer_masked(void)
+{
+	return get_ticks() / (timer_load_val / (100 * CFG_HZ));
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	timestamp = t * (timer_load_val / (100 * CFG_HZ));
+}
+
+void udelay(unsigned long usec)
+{
+	unsigned long long tmp;
+	ulong tmo;
+
+	tmo = (usec + 9) / 10;
+	tmp = get_ticks() + tmo;	/* get current timestamp */
+
+	while (get_ticks() < tmp)/* loop till event */
+		 /*NOP*/;
+}
diff --git a/cpu/arm1176/s3c64xx/speed.c b/cpu/arm1176/s3c64xx/speed.c
new file mode 100644
index 0000000..bb54cb3
--- /dev/null
+++ b/cpu/arm1176/s3c64xx/speed.c
@@ -0,0 +1,140 @@
+/*
+ * (C) Copyright 2001-2004
+ * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+ *
+ * (C) Copyright 2002
+ * David Mueller, ELSOFT AG, d.mueller@elsoft.ch
+ *
+ * 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
+ */
+
+/*
+ * This code should work for both the S3C2400 and the S3C2410
+ * as they seem to have the same PLL and clock machinery inside.
+ * The different address mapping is handled by the s3c24xx.h files below.
+ */
+
+#include <common.h>
+#include <s3c6400.h>
+
+#define APLL 0
+#define MPLL 1
+#define EPLL 2
+
+/* ------------------------------------------------------------------------- */
+/*
+ * NOTE: This describes the proper use of this file.
+ *
+ * CONFIG_SYS_CLK_FREQ should be defined as the input frequency of the PLL.
+ *
+ * get_FCLK(), get_HCLK(), get_PCLK() and get_UCLK() return the clock of
+ * the specified bus in HZ.
+ */
+/* ------------------------------------------------------------------------- */
+
+static ulong get_PLLCLK(int pllreg)
+{
+	ulong r, m, p, s;
+
+	if (pllreg == APLL)
+		r = APLL_CON_REG;
+	else if (pllreg == MPLL)
+		r = MPLL_CON_REG;
+	else if (pllreg == EPLL)
+		r = EPLL_CON0_REG;
+	else
+		hang();
+
+	m = (r >> 16) & 0x3ff;
+	p = (r >> 8) & 0x3f;
+	s = r & 0x7;
+
+	return m * (CONFIG_SYS_CLK_FREQ / (p * (1 << s)));
+}
+
+/* return ARMCORE frequency */
+ulong get_ARMCLK(void)
+{
+	ulong div;
+
+	div = CLK_DIV0_REG;
+
+	return get_PLLCLK(APLL) / ((div & 0x7) + 1);
+}
+
+/* return FCLK frequency */
+ulong get_FCLK(void)
+{
+	return get_PLLCLK(APLL);
+}
+
+/* return HCLK frequency */
+ulong get_HCLK(void)
+{
+	ulong fclk;
+
+	uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
+	uint hclk_div = ((CLK_DIV0_REG >> 8) & 0x1) + 1;
+
+	/*
+	 * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on
+	 * s3c6400 and is always 0, and it is indeed running in ASYNC mode
+	 */
+	if (OTHERS_REG & 0x80)
+		fclk = get_FCLK();		/* SYNC Mode	*/
+	else
+		fclk = get_PLLCLK(MPLL);	/* ASYNC Mode	*/
+
+	return fclk / (hclk_div * hclkx2_div);
+}
+
+/* return PCLK frequency */
+ulong get_PCLK(void)
+{
+	ulong fclk;
+	uint hclkx2_div = ((CLK_DIV0_REG >> 9) & 0x7) + 1;
+	uint pre_div = ((CLK_DIV0_REG >> 12) & 0xf) + 1;
+
+	if (OTHERS_REG & 0x80)
+		fclk = get_FCLK();		/* SYNC Mode	*/
+	else
+		fclk = get_PLLCLK(MPLL);	/* ASYNC Mode	*/
+
+	return fclk / (hclkx2_div * pre_div);
+}
+
+/* return UCLK frequency */
+ulong get_UCLK(void)
+{
+	return get_PLLCLK(EPLL);
+}
+
+int print_cpuinfo(void)
+{
+	printf("\nCPU:     S3C6400@%luMHz\n", get_ARMCLK() / 1000000);
+	printf("         Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz ",
+	       get_FCLK() / 1000000, get_HCLK() / 1000000,
+	       get_PCLK() / 1000000);
+
+	if (OTHERS_REG & 0x80)
+		printf("(SYNC Mode) \n");
+	else
+		printf("(ASYNC Mode) \n");
+	return 0;
+}
diff --git a/cpu/arm1176/start.S b/cpu/arm1176/start.S
new file mode 100644
index 0000000..00cc186
--- /dev/null
+++ b/cpu/arm1176/start.S
@@ -0,0 +1,469 @@
+/*
+ *  armboot - Startup Code for S3C6400/ARM1176 CPU-core
+ *
+ * Copyright (c) 2007	Samsung Electronics
+ *
+ * Copyright (C) 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+ *
+ * 2007-09-21 - Restructured codes by jsgood (jsgood.yang at samsung.com)
+ * 2007-09-21 - Added MoviNAND and OneNAND boot codes by
+ * jsgood (jsgood.yang at samsung.com)
+ * Base codes by scsuh (sc.suh)
+ */
+
+#include <config.h>
+#include <version.h>
+#ifdef CONFIG_ENABLE_MMU
+#include <asm/proc/domain.h>
+#endif
+#include <s3c6400.h>
+
+#if !defined(CONFIG_ENABLE_MMU) && !defined(CFG_PHY_UBOOT_BASE)
+#define CFG_PHY_UBOOT_BASE	CFG_UBOOT_BASE
+#endif
+
+/*
+ *************************************************************************
+ *
+ * Jump vector table as in table 3.1 in [1]
+ *
+ *************************************************************************
+ */
+
+.globl _start
+_start: b	reset
+#ifndef CONFIG_NAND_SPL
+	ldr	pc, _undefined_instruction
+	ldr	pc, _software_interrupt
+	ldr	pc, _prefetch_abort
+	ldr	pc, _data_abort
+	ldr	pc, _not_used
+	ldr	pc, _irq
+	ldr	pc, _fiq
+
+_undefined_instruction:
+	.word undefined_instruction
+_software_interrupt:
+	.word software_interrupt
+_prefetch_abort:
+	.word prefetch_abort
+_data_abort:
+	.word data_abort
+_not_used:
+	.word not_used
+_irq:
+	.word irq
+_fiq:
+	.word fiq
+_pad:
+	.word 0x12345678 /* now 16*4=64 */
+#else
+	. = _start + 64
+#endif
+
+.global _end_vect
+_end_vect:
+	.balignl 16,0xdeadbeef
+/*
+ *************************************************************************
+ *
+ * Startup Code (reset vector)
+ *
+ * do important init only if we don't start from memory!
+ * setup Memory and board specific bits prior to relocation.
+ * relocate armboot to ram
+ * setup stack
+ *
+ *************************************************************************
+ */
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+/*
+ * Below variable is very important because we use MMU in U-Boot.
+ * Without it, we cannot run code correctly before MMU is ON.
+ * by scsuh.
+ */
+_TEXT_PHY_BASE:
+	.word	CFG_PHY_UBOOT_BASE
+
+.globl _armboot_start
+_armboot_start:
+	.word _start
+
+/*
+ * These are defined in the board-specific linker script.
+ */
+.globl _bss_start
+_bss_start:
+	.word __bss_start
+
+.globl _bss_end
+_bss_end:
+	.word _end
+
+/*
+ * the actual reset code
+ */
+
+reset:
+	/*
+	 * set the cpu to SVC32 mode
+	 */
+	mrs	r0,cpsr
+	bic	r0,r0,#0x3f
+	orr	r0,r0,#0xd3
+	msr	cpsr,r0
+
+/*
+ *************************************************************************
+ *
+ * CPU_init_critical registers
+ *
+ * setup important registers
+ * setup memory timing
+ *
+ *************************************************************************
+ */
+	/*
+	 * we do sys-critical inits only at reboot,
+	 * not when booting from ram!
+	 */
+cpu_init_crit:
+	/*
+	 * When booting from NAND - it has definitely been a reset, so, no need
+	 * to flush caches and disable the MMU
+	 */
+#ifndef CONFIG_NAND_SPL
+	/*
+	 * flush v4 I/D caches
+	 */
+	mov	r0, #0
+	mcr	p15, 0, r0, c7, c7, 0	/* flush v3/v4 cache */
+	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
+
+	/*
+	 * disable MMU stuff and caches
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	@ clear bits 13, 9:8 (--V- --RS)
+	bic	r0, r0, #0x00000087	@ clear bits 7, 2:0 (B--- -CAM)
+	orr	r0, r0, #0x00000002	@ set bit 2 (A) Align
+	orr	r0, r0, #0x00001000	@ set bit 12 (I) I-Cache
+	/* Prepare to disable the MMU */
+	adr	r1, mmu_disable_phys
+	/* We presume we're within the first 1024 bytes */
+	and	r1, r1, #0x3fc
+	ldr	r2, _TEXT_PHY_BASE
+	ldr	r3, =0xfff00000
+	and	r2, r2, r3
+	orr	r2, r2, r1
+	b	mmu_disable
+
+	.align 5
+	/* Run in a single cache-line */
+mmu_disable:
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	mov	pc, r2
+#endif
+
+mmu_disable_phys:
+	/* Peri port setup */
+	ldr	r0, =0x70000000
+	orr	r0, r0, #0x13
+	mcr	p15,0,r0,c15,c2,4       @ 256M (0x70000000 - 0x7fffffff)
+
+	/*
+	 * Go setup Memory and board specific bits prior to relocation.
+	 */
+	bl	lowlevel_init		/* go setup pll,mux,memory */
+
+after_copy:
+#ifdef CONFIG_ENABLE_MMU
+enable_mmu:
+	/* enable domain access */
+	ldr	r5, =0x0000ffff
+	mcr	p15, 0, r5, c3, c0, 0	/* load domain access register */
+
+	/* Set the TTB register */
+	ldr	r0, _mmu_table_base
+	ldr	r1, =CFG_PHY_UBOOT_BASE
+	ldr	r2, =0xfff00000
+	bic	r0, r0, r2
+	orr	r1, r0, r1
+	mcr	p15, 0, r1, c2, c0, 0
+
+	/* Enable the MMU */
+	mrc	p15, 0, r0, c1, c0, 0
+	orr	r0, r0, #1		/* Set CR_M to enable MMU */
+
+	/* Prepare to enable the MMU */
+	adr	r1, skip_hw_init
+	and	r1, r1, #0x3fc
+	ldr	r2, _TEXT_BASE
+	ldr	r3, =0xfff00000
+	and	r2, r2, r3
+	orr	r2, r2, r1
+	b	mmu_enable
+
+	.align 5
+	/* Run in a single cache-line */
+mmu_enable:
+
+	mcr	p15, 0, r0, c1, c0, 0
+	nop
+	nop
+	mov	pc, r2
+#endif
+
+skip_hw_init:
+	/* Set up the stack						    */
+stack_setup:
+#ifdef CONFIG_MEMORY_UPPER_CODE
+	ldr	sp, =(CFG_UBOOT_BASE + CFG_UBOOT_SIZE - 0xc)
+#else
+	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
+	sub	r0, r0, #CFG_MALLOC_LEN	/* malloc area                      */
+	sub	r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo                        */
+	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
+
+#endif
+
+clear_bss:
+	ldr	r0, _bss_start		/* find start of bss segment        */
+	ldr	r1, _bss_end		/* stop here                        */
+	mov 	r2, #0			/* clear                            */
+
+clbss_l:
+	str	r2, [r0]		/* clear loop...                    */
+	add	r0, r0, #4
+	cmp	r0, r1
+	ble	clbss_l
+
+#ifndef CONFIG_NAND_SPL
+	ldr	pc, _start_armboot
+
+_start_armboot:
+	.word start_armboot
+#else
+	b	nand_boot
+/*	.word nand_boot*/
+#endif
+
+#ifdef CONFIG_ENABLE_MMU
+_mmu_table_base:
+	.word mmu_table
+#endif
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * we assume that cache operation is done before. (eg. cleanup_before_linux())
+ * actually, we don't need to do anything about cache if not use d-cache in
+ * U-Boot. So, in this function we clean only MMU. by scsuh
+ *
+ * void	theLastJump(void *kernel, int arch_num, uint boot_params);
+ */
+#ifdef CONFIG_ENABLE_MMU
+	.globl theLastJump
+theLastJump:
+	mov	r9, r0
+	ldr	r3, =0xfff00000
+	ldr	r4, _TEXT_PHY_BASE
+	adr	r5, phy_last_jump
+	bic	r5, r5, r3
+	orr	r5, r5, r4
+	mov	pc, r5
+phy_last_jump:
+	/*
+	 * disable MMU stuff
+	 */
+	mrc	p15, 0, r0, c1, c0, 0
+	bic	r0, r0, #0x00002300	/* clear bits 13, 9:8 (--V- --RS) */
+	bic	r0, r0, #0x00000087	/* clear bits 7, 2:0 (B--- -CAM) */
+	orr	r0, r0, #0x00000002	/* set bit 2 (A) Align */
+	orr	r0, r0, #0x00001000	/* set bit 12 (I) I-Cache */
+	mcr	p15, 0, r0, c1, c0, 0
+
+	mcr	p15, 0, r0, c8, c7, 0	/* flush v4 TLB */
+
+	mov	r0, #0
+	mov	pc, r9
+#endif
+/*
+ *************************************************************************
+ *
+ * Interrupt handling
+ *
+ *************************************************************************
+ */
+@
+@ IRQ stack frame.
+@
+#define S_FRAME_SIZE	72
+
+#define S_OLD_R0	68
+#define S_PSR		64
+#define S_PC		60
+#define S_LR		56
+#define S_SP		52
+
+#define S_IP		48
+#define S_FP		44
+#define S_R10		40
+#define S_R9		36
+#define S_R8		32
+#define S_R7		28
+#define S_R6		24
+#define S_R5		20
+#define S_R4		16
+#define S_R3		12
+#define S_R2		8
+#define S_R1		4
+#define S_R0		0
+
+#define MODE_SVC 0x13
+#define I_BIT	 0x80
+
+/*
+ * use bad_save_user_regs for abort/prefetch/undef/swi ...
+ */
+
+	.macro	bad_save_user_regs
+	/* carve out a frame on current user stack */
+	sub	sp, sp, #S_FRAME_SIZE
+	/* Save user registers (now in svc mode) r0-r12 */
+	stmia	sp, {r0 - r12}
+
+	ldr	r2, _armboot_start
+	sub	r2, r2, #(CFG_MALLOC_LEN)
+	/* set base 2 words into abort stack */
+	sub	r2, r2, #(CFG_GBL_DATA_SIZE+8)
+	/* get values for "aborted" pc and cpsr (into parm regs) */
+	ldmia	r2, {r2 - r3}
+	/* grab pointer to old stack */
+	add	r0, sp, #S_FRAME_SIZE
+
+	add	r5, sp, #S_SP
+	mov	r1, lr
+	/* save sp_SVC, lr_SVC, pc, cpsr */
+	stmia	r5, {r0 - r3}
+	/* save current stack into r0 (param register) */
+	mov	r0, sp
+	.endm
+
+	.macro get_bad_stack
+	/* setup our mode stack (enter in banked mode) */
+	ldr	r13, _armboot_start
+	/* move past malloc pool */
+	sub	r13, r13, #(CFG_MALLOC_LEN)
+	/* move to reserved a couple spots for abort stack */
+	sub	r13, r13, #(CFG_GBL_DATA_SIZE + 8)
+
+	/* save caller lr in position 0 of saved stack */
+	str	lr, [r13]
+	/* get the spsr */
+	mrs	lr, spsr
+	/* save spsr in position 1 of saved stack */
+	str	lr, [r13, #4]
+
+	/* prepare SVC-Mode */
+	mov	r13, #MODE_SVC
+	@ msr	spsr_c, r13
+	/* switch modes, make sure moves will execute */
+	msr	spsr, r13
+	/* capture return pc */
+	mov	lr, pc
+	/* jump to next instruction & switch modes. */
+	movs	pc, lr
+	.endm
+
+	.macro get_bad_stack_swi
+	/* space on current stack for scratch reg. */
+	sub	r13, r13, #4
+	/* save R0's value. */
+	str	r0, [r13]
+	/* get data regions start */
+	ldr	r0, _armboot_start
+	/* move past malloc pool */
+	sub	r0, r0, #(CFG_MALLOC_LEN)
+	/* move past gbl and a couple spots for abort stack */
+	sub	r0, r0, #(CFG_GBL_DATA_SIZE + 8)
+	/* save caller lr in position 0 of saved stack */
+	str	lr, [r0]
+	/* get the spsr */
+	mrs	r0, spsr
+	/* save spsr in position 1 of saved stack */
+	str	lr, [r0, #4]
+	/* restore r0 */
+	ldr	r0, [r13]
+	/* pop stack entry */
+	add	r13, r13, #4
+	.endm
+
+/*
+ * exception handlers
+ */
+	.align	5
+undefined_instruction:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_undefined_instruction
+
+	.align	5
+software_interrupt:
+	get_bad_stack_swi
+	bad_save_user_regs
+	bl	do_software_interrupt
+
+	.align	5
+prefetch_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_prefetch_abort
+
+	.align	5
+data_abort:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_data_abort
+
+	.align	5
+not_used:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_not_used
+
+	.align	5
+irq:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_irq
+
+	.align	5
+fiq:
+	get_bad_stack
+	bad_save_user_regs
+	bl	do_fiq
+#endif /* CONFIG_NAND_SPL */
diff --git a/include/asm-arm/arch-s3c64xx/hardware.h b/include/asm-arm/arch-s3c64xx/hardware.h
new file mode 100644
index 0000000..84d24c9
--- /dev/null
+++ b/include/asm-arm/arch-s3c64xx/hardware.h
@@ -0,0 +1,63 @@
+/*
+ * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 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 _ARCH_HARDWARE_H_
+#define _ARCH_HARDWARE_H_
+
+#include <asm/sizes.h>
+
+#ifndef __ASSEMBLY__
+#define UData(Data)	((unsigned long) (Data))
+
+#define __REG(x)	(*(vu_long *)(x))
+#define __REGl(x)	(*(vu_long *)(x))
+#define __REGw(x)	(*(vu_short *)(x))
+#define __REGb(x)	(*(vu_char *)(x))
+#define __REG2(x, y)	(*(vu_long *)((x) + (y)))
+#else
+#define UData(Data)	(Data)
+
+#define __REG(x)	(x)
+#define __REGl(x)	(x)
+#define __REGw(x)	(x)
+#define __REGb(x)	(x)
+#define __REG2(x, y)	((x) + (y))
+#endif
+
+#define Fld(Size, Shft)	(((Size) << 16) + (Shft))
+
+#define FSize(Field)	((Field) >> 16)
+#define FShft(Field)	((Field) & 0x0000FFFF)
+#define FMsk(Field)	(((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field)	((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field)	(UData (1) << FShft (Field))
+
+#define FClrBit(Data, Bit)	(Data = (Data & ~(Bit)))
+#define FClrFld(Data, Field)	(Data = (Data & ~FMsk(Field)))
+
+#define FInsrt(Value, Field) \
+			(UData (Value) << FShft (Field))
+
+#define FExtr(Data, Field) \
+			((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+#endif /* _ARCH_HARDWARE_H_ */
diff --git a/include/common.h b/include/common.h
index 2fcb1fd..10d56e0 100644
--- a/include/common.h
+++ b/include/common.h
@@ -489,7 +489,8 @@ int	prt_mpc8220_clks (void);
 ulong	get_OPB_freq (void);
 ulong	get_PCI_freq (void);
 #endif
-#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_LH7A40X)
+#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || \
+	defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400)
 void	s3c2410_irq(void);
 #define ARM920_IRQ_CALLBACK s3c2410_irq
 ulong	get_FCLK (void);
diff --git a/include/s3c6400.h b/include/s3c6400.h
new file mode 100644
index 0000000..8814747
--- /dev/null
+++ b/include/s3c6400.h
@@ -0,0 +1,884 @@
+/*
+ * (C) Copyright 2007
+ * Byungjae Lee, Samsung Erectronics, bjlee at samsung.com.
+ *      - only support for S3C6400
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
+ *
+ * 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	    : s3c6400.h
+ *
+ * Based on S3C6400 User's manual Rev 0.0
+ ************************************************/
+
+#ifndef __S3C6400_H__
+#define __S3C6400_H__
+
+#ifndef CONFIG_S3C6400
+#define CONFIG_S3C6400		1
+#endif
+
+#define S3C64XX_UART_CHANNELS	3
+#define S3C64XX_SPI_CHANNELS	2
+
+#include <asm/hardware.h>
+
+#define ELFIN_CLOCK_POWER_BASE	0x7e00f000
+
+/* Clock & Power Controller for mDirac3*/
+#define APLL_LOCK_OFFSET	0x00
+#define MPLL_LOCK_OFFSET	0x04
+#define EPLL_LOCK_OFFSET	0x08
+#define APLL_CON_OFFSET		0x0C
+#define MPLL_CON_OFFSET		0x10
+#define EPLL_CON0_OFFSET	0x14
+#define EPLL_CON1_OFFSET	0x18
+#define CLK_SRC_OFFSET		0x1C
+#define CLK_DIV0_OFFSET		0x20
+#define CLK_DIV1_OFFSET		0x24
+#define CLK_DIV2_OFFSET		0x28
+#define CLK_OUT_OFFSET		0x2C
+#define HCLK_GATE_OFFSET	0x30
+#define PCLK_GATE_OFFSET	0x34
+#define SCLK_GATE_OFFSET	0x38
+#define AHB_CON0_OFFSET		0x100
+#define AHB_CON1_OFFSET		0x104
+#define AHB_CON2_OFFSET		0x108
+#define SELECT_DMA_OFFSET	0x110
+#define SW_RST_OFFSET		0x114
+#define SYS_ID_OFFSET		0x118
+#define MEM_SYS_CFG_OFFSET	0x120
+#define QOS_OVERRIDE0_OFFSET	0x124
+#define QOS_OVERRIDE1_OFFSET	0x128
+#define MEM_CFG_STAT_OFFSET	0x12C
+#define PWR_CFG_OFFSET		0x804
+#define EINT_MASK_OFFSET	0x808
+#define NOR_CFG_OFFSET		0x810
+#define STOP_CFG_OFFSET		0x814
+#define SLEEP_CFG_OFFSET	0x818
+#define OSC_FREQ_OFFSET		0x820
+#define OSC_STABLE_OFFSET	0x824
+#define PWR_STABLE_OFFSET	0x828
+#define FPC_STABLE_OFFSET	0x82C
+#define MTC_STABLE_OFFSET	0x830
+#define OTHERS_OFFSET		0x900
+#define RST_STAT_OFFSET		0x904
+#define WAKEUP_STAT_OFFSET	0x908
+#define BLK_PWR_STAT_OFFSET	0x90C
+#define INF_REG0_OFFSET		0xA00
+#define INF_REG1_OFFSET		0xA04
+#define INF_REG2_OFFSET		0xA08
+#define INF_REG3_OFFSET		0xA0C
+#define INF_REG4_OFFSET		0xA10
+#define INF_REG5_OFFSET		0xA14
+#define INF_REG6_OFFSET		0xA18
+#define INF_REG7_OFFSET		0xA1C
+
+#define OSC_CNT_VAL_OFFSET	0x824
+#define PWR_CNT_VAL_OFFSET	0x828
+#define FPC_CNT_VAL_OFFSET	0x82C
+#define MTC_CNT_VAL_OFFSET	0x830
+
+#define APLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET)
+#define MPLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET)
+#define EPLL_LOCK_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET)
+#define APLL_CON_REG		__REG(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET)
+#define MPLL_CON_REG		__REG(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET)
+#define EPLL_CON0_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET)
+#define EPLL_CON1_REG		__REG(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET)
+#define CLK_SRC_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET)
+#define CLK_DIV0_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET)
+#define CLK_DIV1_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET)
+#define CLK_DIV2_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET)
+#define CLK_OUT_REG		__REG(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET)
+#define HCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET)
+#define PCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET)
+#define SCLK_GATE_REG		__REG(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET)
+#define AHB_CON0_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET)
+#define AHB_CON1_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET)
+#define AHB_CON2_REG		__REG(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET)
+#define SELECT_DMA_REG		__REG(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET)
+#define SW_RST_REG		__REG(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET)
+#define SYS_ID_REG		__REG(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET)
+#define MEM_SYS_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET)
+#define QOS_OVERRIDE0_REG	__REG(ELFIN_CLOCK_POWER_BASE+ \
+				      QOS_OVERRIDE0_OFFSET)
+#define QOS_OVERRIDE1_REG	__REG(ELFIN_CLOCK_POWER_BASE+ \
+				      QOS_OVERRIDE1_OFFSET)
+#define MEM_CFG_STAT_REG	__REG(ELFIN_CLOCK_POWER_BASE+ \
+				      MEM_CFG_STAT_OFFSET)
+#define PWR_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET)
+#define EINT_MASK_REG		__REG(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET)
+#define NOR_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET)
+#define STOP_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET)
+#define SLEEP_CFG_REG		__REG(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET)
+#define OSC_FREQ_REG		__REG(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET)
+#define OSC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET)
+#define PWR_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET)
+#define FPC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET)
+#define MTC_CNT_VAL_REG		__REG(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET)
+#define OTHERS_REG		__REG(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET)
+#define RST_STAT_REG		__REG(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
+#define WAKEUP_STAT_REG		__REG(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)
+#define BLK_PWR_STAT_REG	__REG(ELFIN_CLOCK_POWER_BASE+ \
+				      BLK_PWR_STAT_OFFSET)
+#define INF_REG0_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)
+#define INF_REG1_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET)
+#define INF_REG2_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET)
+#define INF_REG3_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET)
+#define INF_REG4_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET)
+#define INF_REG5_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET)
+#define INF_REG6_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET)
+#define INF_REG7_REG		__REG(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET)
+
+#define APLL_LOCK	(ELFIN_CLOCK_POWER_BASE+APLL_LOCK_OFFSET)
+#define MPLL_LOCK	(ELFIN_CLOCK_POWER_BASE+MPLL_LOCK_OFFSET)
+#define EPLL_LOCK	(ELFIN_CLOCK_POWER_BASE+EPLL_LOCK_OFFSET)
+#define APLL_CON	(ELFIN_CLOCK_POWER_BASE+APLL_CON_OFFSET)
+#define MPLL_CON	(ELFIN_CLOCK_POWER_BASE+MPLL_CON_OFFSET)
+#define EPLL_CON0	(ELFIN_CLOCK_POWER_BASE+EPLL_CON0_OFFSET)
+#define EPLL_CON1	(ELFIN_CLOCK_POWER_BASE+EPLL_CON1_OFFSET)
+#define CLK_SRC		(ELFIN_CLOCK_POWER_BASE+CLK_SRC_OFFSET)
+#define CLK_DIV0	(ELFIN_CLOCK_POWER_BASE+CLK_DIV0_OFFSET)
+#define CLK_DIV1	(ELFIN_CLOCK_POWER_BASE+CLK_DIV1_OFFSET)
+#define CLK_DIV2	(ELFIN_CLOCK_POWER_BASE+CLK_DIV2_OFFSET)
+#define CLK_OUT		(ELFIN_CLOCK_POWER_BASE+CLK_OUT_OFFSET)
+#define HCLK_GATE	(ELFIN_CLOCK_POWER_BASE+HCLK_GATE_OFFSET)
+#define PCLK_GATE	(ELFIN_CLOCK_POWER_BASE+PCLK_GATE_OFFSET)
+#define SCLK_GATE	(ELFIN_CLOCK_POWER_BASE+SCLK_GATE_OFFSET)
+#define AHB_CON0	(ELFIN_CLOCK_POWER_BASE+AHB_CON0_OFFSET)
+#define AHB_CON1	(ELFIN_CLOCK_POWER_BASE+AHB_CON1_OFFSET)
+#define AHB_CON2	(ELFIN_CLOCK_POWER_BASE+AHB_CON2_OFFSET)
+#define SELECT_DMA	(ELFIN_CLOCK_POWER_BASE+SELECT_DMA_OFFSET)
+#define SW_RST		(ELFIN_CLOCK_POWER_BASE+SW_RST_OFFSET)
+#define SYS_ID		(ELFIN_CLOCK_POWER_BASE+SYS_ID_OFFSET)
+#define MEM_SYS_CFG	(ELFIN_CLOCK_POWER_BASE+MEM_SYS_CFG_OFFSET)
+#define QOS_OVERRIDE0	(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE0_OFFSET)
+#define QOS_OVERRIDE1	(ELFIN_CLOCK_POWER_BASE+QOS_OVERRIDE1_OFFSET)
+#define MEM_CFG_STAT	(ELFIN_CLOCK_POWER_BASE+MEM_CFG_STAT_OFFSET)
+#define PWR_CFG		(ELFIN_CLOCK_POWER_BASE+PWR_CFG_OFFSET)
+#define EINT_MASK	(ELFIN_CLOCK_POWER_BASE+EINT_MASK_OFFSET)
+#define NOR_CFG		(ELFIN_CLOCK_POWER_BASE+NOR_CFG_OFFSET)
+#define STOP_CFG	(ELFIN_CLOCK_POWER_BASE+STOP_CFG_OFFSET)
+#define SLEEP_CFG	(ELFIN_CLOCK_POWER_BASE+SLEEP_CFG_OFFSET)
+#define OSC_FREQ	(ELFIN_CLOCK_POWER_BASE+OSC_FREQ_OFFSET)
+#define OSC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+OSC_CNT_VAL_OFFSET)
+#define PWR_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+PWR_CNT_VAL_OFFSET)
+#define FPC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+FPC_CNT_VAL_OFFSET)
+#define MTC_CNT_VAL	(ELFIN_CLOCK_POWER_BASE+MTC_CNT_VAL_OFFSET)
+#define OTHERS		(ELFIN_CLOCK_POWER_BASE+OTHERS_OFFSET)
+#define RST_STAT	(ELFIN_CLOCK_POWER_BASE+RST_STAT_OFFSET)
+#define WAKEUP_STAT	(ELFIN_CLOCK_POWER_BASE+WAKEUP_STAT_OFFSET)
+#define BLK_PWR_STAT	(ELFIN_CLOCK_POWER_BASE+BLK_PWR_STAT_OFFSET)
+#define INF_REG0	(ELFIN_CLOCK_POWER_BASE+INF_REG0_OFFSET)
+#define INF_REG1	(ELFIN_CLOCK_POWER_BASE+INF_REG1_OFFSET)
+#define INF_REG2	(ELFIN_CLOCK_POWER_BASE+INF_REG2_OFFSET)
+#define INF_REG3	(ELFIN_CLOCK_POWER_BASE+INF_REG3_OFFSET)
+#define INF_REG4	(ELFIN_CLOCK_POWER_BASE+INF_REG4_OFFSET)
+#define INF_REG5	(ELFIN_CLOCK_POWER_BASE+INF_REG5_OFFSET)
+#define INF_REG6	(ELFIN_CLOCK_POWER_BASE+INF_REG6_OFFSET)
+#define INF_REG7	(ELFIN_CLOCK_POWER_BASE+INF_REG7_OFFSET)
+
+
+/*
+ * GPIO
+ */
+#define ELFIN_GPIO_BASE		0x7f008000
+
+#define GPACON_OFFSET		0x00
+#define GPADAT_OFFSET		0x04
+#define GPAPUD_OFFSET		0x08
+#define GPACONSLP_OFFSET	0x0C
+#define GPAPUDSLP_OFFSET	0x10
+#define GPBCON_OFFSET		0x20
+#define GPBDAT_OFFSET		0x04
+#define GPBPUD_OFFSET		0x08
+#define GPBCONSLP_OFFSET	0x0C
+#define GPBPUDSLP_OFFSET	0x30
+#define GPCCON_OFFSET		0x40
+#define GPCDAT_OFFSET		0x44
+#define GPCPUD_OFFSET		0x48
+#define GPCCONSLP_OFFSET	0x4C
+#define GPCPUDSLP_OFFSET	0x50
+#define GPDCON_OFFSET		0x60
+#define GPDDAT_OFFSET		0x64
+#define GPDPUD_OFFSET		0x68
+#define GPDCONSLP_OFFSET	0x6C
+#define GPDPUDSLP_OFFSET	0x70
+#define GPECON_OFFSET		0x80
+#define GPEDAT_OFFSET		0x84
+#define GPEPUD_OFFSET		0x88
+#define GPECONSLP_OFFSET	0x8C
+#define GPEPUDSLP_OFFSET	0x90
+#define GPFCON_OFFSET		0xA0
+#define GPFDAT_OFFSET		0xA4
+#define GPFPUD_OFFSET		0xA8
+#define GPFCONSLP_OFFSET	0xAC
+#define GPFPUDSLP_OFFSET	0xB0
+#define GPGCON_OFFSET		0xC0
+#define GPGDAT_OFFSET		0xC4
+#define GPGPUD_OFFSET		0xC8
+#define GPGCONSLP_OFFSET	0xCC
+#define GPGPUDSLP_OFFSET	0xD0
+#define GPHCON0_OFFSET		0xE0
+#define GPHCON1_OFFSET		0xE4
+#define GPHDAT_OFFSET		0xE8
+#define GPHPUD_OFFSET		0xEC
+#define GPHCONSLP_OFFSET	0xF0
+#define GPHPUDSLP_OFFSET	0xF4
+#define GPICON_OFFSET		0x100
+#define GPIDAT_OFFSET		0x104
+#define GPIPUD_OFFSET		0x108
+#define GPICONSLP_OFFSET	0x10C
+#define GPIPUDSLP_OFFSET	0x110
+#define GPJCON_OFFSET		0x120
+#define GPJDAT_OFFSET		0x124
+#define GPJPUD_OFFSET		0x128
+#define GPJCONSLP_OFFSET	0x12C
+#define GPJPUDSLP_OFFSET	0x130
+#define MEM0DRVCON_OFFSET	0x1D0
+#define MEM1DRVCON_OFFSET	0x1D4
+#define GPKCON0_OFFSET		0x800
+#define GPKCON1_OFFSET		0x804
+#define GPKDAT_OFFSET		0x808
+#define GPKPUD_OFFSET		0x80C
+#define GPLCON0_OFFSET		0x810
+#define GPLCON1_OFFSET		0x814
+#define GPLDAT_OFFSET		0x818
+#define GPLPUD_OFFSET		0x81C
+#define GPMCON_OFFSET		0x820
+#define GPMDAT_OFFSET		0x824
+#define GPMPUD_OFFSET		0x828
+#define GPNCON_OFFSET		0x830
+#define GPNDAT_OFFSET		0x834
+#define GPNPUD_OFFSET		0x838
+#define GPOCON_OFFSET		0x140
+#define GPODAT_OFFSET		0x144
+#define GPOPUD_OFFSET		0x148
+#define GPOCONSLP_OFFSET	0x14C
+#define GPOPUDSLP_OFFSET	0x150
+#define GPPCON_OFFSET		0x160
+#define GPPDAT_OFFSET		0x164
+#define GPPPUD_OFFSET		0x168
+#define GPPCONSLP_OFFSET	0x16C
+#define GPPPUDSLP_OFFSET	0x170
+#define GPQCON_OFFSET		0x180
+#define GPQDAT_OFFSET		0x184
+#define GPQPUD_OFFSET		0x188
+#define GPQCONSLP_OFFSET	0x18C
+#define GPQPUDSLP_OFFSET	0x190
+
+#define EINTPEND_OFFSET		0x924
+
+#define GPACON_REG		__REG(ELFIN_GPIO_BASE+GPACON_OFFSET)
+#define GPADAT_REG		__REG(ELFIN_GPIO_BASE+GPADAT_OFFSET)
+#define GPAPUD_REG		__REG(ELFIN_GPIO_BASE+GPAPUD_OFFSET)
+#define GPACONSLP_REG		__REG(ELFIN_GPIO_BASE+GPACONSLP_OFFSET)
+#define GPAPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET)
+#define GPBCON_REG		__REG(ELFIN_GPIO_BASE+GPBCON_OFFSET)
+#define GPBDAT_REG		__REG(ELFIN_GPIO_BASE+GPBDAT_OFFSET)
+#define GPBPUD_REG		__REG(ELFIN_GPIO_BASE+GPBPUD_OFFSET)
+#define GPBCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET)
+#define GPBPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET)
+#define GPCCON_REG		__REG(ELFIN_GPIO_BASE+GPCCON_OFFSET)
+#define GPCDAT_REG		__REG(ELFIN_GPIO_BASE+GPCDAT_OFFSET)
+#define GPCPUD_REG		__REG(ELFIN_GPIO_BASE+GPCPUD_OFFSET)
+#define GPCCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET)
+#define GPCPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET)
+#define GPDCON_REG		__REG(ELFIN_GPIO_BASE+GPDCON_OFFSET)
+#define GPDDAT_REG		__REG(ELFIN_GPIO_BASE+GPDDAT_OFFSET)
+#define GPDPUD_REG		__REG(ELFIN_GPIO_BASE+GPDPUD_OFFSET)
+#define GPDCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET)
+#define GPDPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET)
+#define GPECON_REG		__REG(ELFIN_GPIO_BASE+GPECON_OFFSET)
+#define GPEDAT_REG		__REG(ELFIN_GPIO_BASE+GPEDAT_OFFSET)
+#define GPEPUD_REG		__REG(ELFIN_GPIO_BASE+GPEPUD_OFFSET)
+#define GPECONSLP_REG		__REG(ELFIN_GPIO_BASE+GPECONSLP_OFFSET)
+#define GPEPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET)
+#define GPFCON_REG		__REG(ELFIN_GPIO_BASE+GPFCON_OFFSET)
+#define GPFDAT_REG		__REG(ELFIN_GPIO_BASE+GPFDAT_OFFSET)
+#define GPFPUD_REG		__REG(ELFIN_GPIO_BASE+GPFPUD_OFFSET)
+#define GPFCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET)
+#define GPFPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET)
+#define GPGCON_REG		__REG(ELFIN_GPIO_BASE+GPGCON_OFFSET)
+#define GPGDAT_REG		__REG(ELFIN_GPIO_BASE+GPGDAT_OFFSET)
+#define GPGPUD_REG		__REG(ELFIN_GPIO_BASE+GPGPUD_OFFSET)
+#define GPGCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET)
+#define GPGPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET)
+#define GPHCON0_REG		__REG(ELFIN_GPIO_BASE+GPHCON0_OFFSET)
+#define GPHCON1_REG		__REG(ELFIN_GPIO_BASE+GPHCON1_OFFSET)
+#define GPHDAT_REG		__REG(ELFIN_GPIO_BASE+GPHDAT_OFFSET)
+#define GPHPUD_REG		__REG(ELFIN_GPIO_BASE+GPHPUD_OFFSET)
+#define GPHCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET)
+#define GPHPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET)
+#define GPICON_REG		__REG(ELFIN_GPIO_BASE+GPICON_OFFSET)
+#define GPIDAT_REG		__REG(ELFIN_GPIO_BASE+GPIDAT_OFFSET)
+#define GPIPUD_REG		__REG(ELFIN_GPIO_BASE+GPIPUD_OFFSET)
+#define GPICONSLP_REG		__REG(ELFIN_GPIO_BASE+GPICONSLP_OFFSET)
+#define GPIPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET)
+#define GPJCON_REG		__REG(ELFIN_GPIO_BASE+GPJCON_OFFSET)
+#define GPJDAT_REG		__REG(ELFIN_GPIO_BASE+GPJDAT_OFFSET)
+#define GPJPUD_REG		__REG(ELFIN_GPIO_BASE+GPJPUD_OFFSET)
+#define GPJCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET)
+#define GPJPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET)
+#define GPKCON0_REG		__REG(ELFIN_GPIO_BASE+GPKCON0_OFFSET)
+#define GPKCON1_REG		__REG(ELFIN_GPIO_BASE+GPKCON1_OFFSET)
+#define GPKDAT_REG		__REG(ELFIN_GPIO_BASE+GPKDAT_OFFSET)
+#define GPKPUD_REG		__REG(ELFIN_GPIO_BASE+GPKPUD_OFFSET)
+#define GPLCON0_REG		__REG(ELFIN_GPIO_BASE+GPLCON0_OFFSET)
+#define GPLCON1_REG		__REG(ELFIN_GPIO_BASE+GPLCON1_OFFSET)
+#define GPLDAT_REG		__REG(ELFIN_GPIO_BASE+GPLDAT_OFFSET)
+#define GPLPUD_REG		__REG(ELFIN_GPIO_BASE+GPLPUD_OFFSET)
+#define GPMCON_REG		__REG(ELFIN_GPIO_BASE+GPMCON_OFFSET)
+#define GPMDAT_REG		__REG(ELFIN_GPIO_BASE+GPMDAT_OFFSET)
+#define GPMPUD_REG		__REG(ELFIN_GPIO_BASE+GPMPUD_OFFSET)
+#define GPNCON_REG		__REG(ELFIN_GPIO_BASE+GPNCON_OFFSET)
+#define GPNDAT_REG		__REG(ELFIN_GPIO_BASE+GPNDAT_OFFSET)
+#define GPNPUD_REG		__REG(ELFIN_GPIO_BASE+GPNPUD_OFFSET)
+#define GPOCON_REG		__REG(ELFIN_GPIO_BASE+GPOCON_OFFSET)
+#define GPODAT_REG		__REG(ELFIN_GPIO_BASE+GPODAT_OFFSET)
+#define GPOPUD_REG		__REG(ELFIN_GPIO_BASE+GPOPUD_OFFSET)
+#define GPOCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET)
+#define GPOPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET)
+#define GPPCON_REG		__REG(ELFIN_GPIO_BASE+GPPCON_OFFSET)
+#define GPPDAT_REG		__REG(ELFIN_GPIO_BASE+GPPDAT_OFFSET)
+#define GPPPUD_REG		__REG(ELFIN_GPIO_BASE+GPPPUD_OFFSET)
+#define GPPCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET)
+#define GPPPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET)
+#define GPQCON_REG		__REG(ELFIN_GPIO_BASE+GPQCON_OFFSET)
+#define GPQDAT_REG		__REG(ELFIN_GPIO_BASE+GPQDAT_OFFSET)
+#define GPQPUD_REG		__REG(ELFIN_GPIO_BASE+GPQPUD_OFFSET)
+#define GPQCONSLP_REG		__REG(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET)
+#define GPQPUDSLP_REG		__REG(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET)
+
+/*
+ * Bus Matrix
+ */
+#define ELFIN_MEM_SYS_CFG      0x7e00f120
+
+#define GPACON		(ELFIN_GPIO_BASE+GPACON_OFFSET)
+#define GPADAT		(ELFIN_GPIO_BASE+GPADAT_OFFSET)
+#define GPAPUD		(ELFIN_GPIO_BASE+GPAPUD_OFFSET)
+#define GPACONSLP	(ELFIN_GPIO_BASE+GPACONSLP_OFFSET)
+#define GPAPUDSLP	(ELFIN_GPIO_BASE+GPAPUDSLP_OFFSET)
+#define GPBCON		(ELFIN_GPIO_BASE+GPBCON_OFFSET)
+#define GPBDAT		(ELFIN_GPIO_BASE+GPBDAT_OFFSET)
+#define GPBPUD		(ELFIN_GPIO_BASE+GPBPUD_OFFSET)
+#define GPBCONSLP	(ELFIN_GPIO_BASE+GPBCONSLP_OFFSET)
+#define GPBPUDSLP	(ELFIN_GPIO_BASE+GPBPUDSLP_OFFSET)
+#define GPCCON		(ELFIN_GPIO_BASE+GPCCON_OFFSET)
+#define GPCDAT		(ELFIN_GPIO_BASE+GPCDAT_OFFSET)
+#define GPCPUD		(ELFIN_GPIO_BASE+GPCPUD_OFFSET)
+#define GPCCONSLP	(ELFIN_GPIO_BASE+GPCCONSLP_OFFSET)
+#define GPCPUDSLP	(ELFIN_GPIO_BASE+GPCPUDSLP_OFFSET)
+#define GPDCON		(ELFIN_GPIO_BASE+GPDCON_OFFSET)
+#define GPDDAT		(ELFIN_GPIO_BASE+GPDDAT_OFFSET)
+#define GPDPUD		(ELFIN_GPIO_BASE+GPDPUD_OFFSET)
+#define GPDCONSLP	(ELFIN_GPIO_BASE+GPDCONSLP_OFFSET)
+#define GPDPUDSLP	(ELFIN_GPIO_BASE+GPDPUDSLP_OFFSET)
+#define GPECON		(ELFIN_GPIO_BASE+GPECON_OFFSET)
+#define GPEDAT		(ELFIN_GPIO_BASE+GPEDAT_OFFSET)
+#define GPEPUD		(ELFIN_GPIO_BASE+GPEPUD_OFFSET)
+#define GPECONSLP	(ELFIN_GPIO_BASE+GPECONSLP_OFFSET)
+#define GPEPUDSLP	(ELFIN_GPIO_BASE+GPEPUDSLP_OFFSET)
+#define GPFCON		(ELFIN_GPIO_BASE+GPFCON_OFFSET)
+#define GPFDAT		(ELFIN_GPIO_BASE+GPFDAT_OFFSET)
+#define GPFPUD		(ELFIN_GPIO_BASE+GPFPUD_OFFSET)
+#define GPFCONSLP	(ELFIN_GPIO_BASE+GPFCONSLP_OFFSET)
+#define GPFPUDSLP	(ELFIN_GPIO_BASE+GPFPUDSLP_OFFSET)
+#define GPGCON		(ELFIN_GPIO_BASE+GPGCON_OFFSET)
+#define GPGDAT		(ELFIN_GPIO_BASE+GPGDAT_OFFSET)
+#define GPGPUD		(ELFIN_GPIO_BASE+GPGPUD_OFFSET)
+#define GPGCONSLP	(ELFIN_GPIO_BASE+GPGCONSLP_OFFSET)
+#define GPGPUDSLP	(ELFIN_GPIO_BASE+GPGPUDSLP_OFFSET)
+#define GPHCON0		(ELFIN_GPIO_BASE+GPHCON0_OFFSET)
+#define GPHCON1		(ELFIN_GPIO_BASE+GPHCON1_OFFSET)
+#define GPHDAT		(ELFIN_GPIO_BASE+GPHDAT_OFFSET)
+#define GPHPUD		(ELFIN_GPIO_BASE+GPHPUD_OFFSET)
+#define GPHCONSLP	(ELFIN_GPIO_BASE+GPHCONSLP_OFFSET)
+#define GPHPUDSLP	(ELFIN_GPIO_BASE+GPHPUDSLP_OFFSET)
+#define GPICON		(ELFIN_GPIO_BASE+GPICON_OFFSET)
+#define GPIDAT		(ELFIN_GPIO_BASE+GPIDAT_OFFSET)
+#define GPIPUD		(ELFIN_GPIO_BASE+GPIPUD_OFFSET)
+#define GPICONSLP	(ELFIN_GPIO_BASE+GPICONSLP_OFFSET)
+#define GPIPUDSLP	(ELFIN_GPIO_BASE+GPIPUDSLP_OFFSET)
+#define GPJCON		(ELFIN_GPIO_BASE+GPJCON_OFFSET)
+#define GPJDAT		(ELFIN_GPIO_BASE+GPJDAT_OFFSET)
+#define GPJPUD		(ELFIN_GPIO_BASE+GPJPUD_OFFSET)
+#define GPJCONSLP	(ELFIN_GPIO_BASE+GPJCONSLP_OFFSET)
+#define GPJPUDSLP	(ELFIN_GPIO_BASE+GPJPUDSLP_OFFSET)
+#define GPKCON0		(ELFIN_GPIO_BASE+GPKCON0_OFFSET)
+#define GPKCON1		(ELFIN_GPIO_BASE+GPKCON1_OFFSET)
+#define GPKDAT		(ELFIN_GPIO_BASE+GPKDAT_OFFSET)
+#define GPKPUD		(ELFIN_GPIO_BASE+GPKPUD_OFFSET)
+#define GPLCON0		(ELFIN_GPIO_BASE+GPLCON0_OFFSET)
+#define GPLCON1		(ELFIN_GPIO_BASE+GPLCON1_OFFSET)
+#define GPLDAT		(ELFIN_GPIO_BASE+GPLDAT_OFFSET)
+#define GPLPUD		(ELFIN_GPIO_BASE+GPLPUD_OFFSET)
+#define GPMCON		(ELFIN_GPIO_BASE+GPMCON_OFFSET)
+#define GPMDAT		(ELFIN_GPIO_BASE+GPMDAT_OFFSET)
+#define GPMPUD		(ELFIN_GPIO_BASE+GPMPUD_OFFSET)
+#define GPNCON		(ELFIN_GPIO_BASE+GPNCON_OFFSET)
+#define GPNDAT		(ELFIN_GPIO_BASE+GPNDAT_OFFSET)
+#define GPNPUD		(ELFIN_GPIO_BASE+GPNPUD_OFFSET)
+#define GPOCON		(ELFIN_GPIO_BASE+GPOCON_OFFSET)
+#define GPODAT		(ELFIN_GPIO_BASE+GPODAT_OFFSET)
+#define GPOPUD		(ELFIN_GPIO_BASE+GPOPUD_OFFSET)
+#define GPOCONSLP	(ELFIN_GPIO_BASE+GPOCONSLP_OFFSET)
+#define GPOPUDSLP	(ELFIN_GPIO_BASE+GPOPUDSLP_OFFSET)
+#define GPPCON		(ELFIN_GPIO_BASE+GPPCON_OFFSET)
+#define GPPDAT		(ELFIN_GPIO_BASE+GPPDAT_OFFSET)
+#define GPPPUD		(ELFIN_GPIO_BASE+GPPPUD_OFFSET)
+#define GPPCONSLP	(ELFIN_GPIO_BASE+GPPCONSLP_OFFSET)
+#define GPPPUDSLP	(ELFIN_GPIO_BASE+GPPPUDSLP_OFFSET)
+#define GPQCON		(ELFIN_GPIO_BASE+GPQCON_OFFSET)
+#define GPQDAT		(ELFIN_GPIO_BASE+GPQDAT_OFFSET)
+#define GPQPUD		(ELFIN_GPIO_BASE+GPQPUD_OFFSET)
+#define GPQCONSLP	(ELFIN_GPIO_BASE+GPQCONSLP_OFFSET)
+#define GPQPUDSLP	(ELFIN_GPIO_BASE+GPQPUDSLP_OFFSET)
+
+/*
+ * Memory controller
+ */
+#define ELFIN_SROM_BASE                0x70000000
+
+#define SROM_BW_REG            __REG(ELFIN_SROM_BASE+0x0)
+#define SROM_BC0_REG           __REG(ELFIN_SROM_BASE+0x4)
+#define SROM_BC1_REG           __REG(ELFIN_SROM_BASE+0x8)
+#define SROM_BC2_REG           __REG(ELFIN_SROM_BASE+0xC)
+#define SROM_BC3_REG           __REG(ELFIN_SROM_BASE+0x10)
+#define SROM_BC4_REG           __REG(ELFIN_SROM_BASE+0x14)
+#define SROM_BC5_REG           __REG(ELFIN_SROM_BASE+0x18)
+
+/*
+ * SDRAM Controller
+ */
+#define ELFIN_DMC0_BASE		0x7e000000
+#define ELFIN_DMC1_BASE		0x7e001000
+
+#define INDEX_DMC_MEMC_STATUS   (0x00)
+#define INDEX_DMC_MEMC_CMD      (0x04)
+#define INDEX_DMC_DIRECT_CMD    (0x08)
+#define INDEX_DMC_MEMORY_CFG    (0x0C)
+#define INDEX_DMC_REFRESH_PRD   (0x10)
+#define INDEX_DMC_CAS_LATENCY   (0x14)
+#define INDEX_DMC_T_DQSS        (0x18)
+#define INDEX_DMC_T_MRD         (0x1C)
+#define INDEX_DMC_T_RAS         (0x20)
+#define INDEX_DMC_T_RC          (0x24)
+#define INDEX_DMC_T_RCD         (0x28)
+#define INDEX_DMC_T_RFC         (0x2C)
+#define INDEX_DMC_T_RP          (0x30)
+#define INDEX_DMC_T_RRD         (0x34)
+#define INDEX_DMC_T_WR          (0x38)
+#define INDEX_DMC_T_WTR         (0x3C)
+#define INDEX_DMC_T_XP          (0x40)
+#define INDEX_DMC_T_XSR         (0x44)
+#define INDEX_DMC_T_ESR         (0x48)
+#define INDEX_DMC_MEMORY_CFG2	(0x4C)
+#define INDEX_DMC_CHIP_0_CFG    (0x200)
+#define INDEX_DMC_CHIP_1_CFG    (0x204)
+#define INDEX_DMC_CHIP_2_CFG    (0x208)
+#define INDEX_DMC_CHIP_3_CFG    (0x20C)
+#define INDEX_DMC_USER_STATUS	(0x300)
+#define INDEX_DMC_USER_CONFIG	(0x304)
+
+/*
+ * Memory Chip direct command
+ */
+#define DMC_NOP0	0x0c0000
+#define DMC_NOP1	0x1c0000
+#define DMC_PA0		0x000000        /* Precharge all */
+#define DMC_PA1		0x100000
+#define DMC_AR0		0x040000        /* Autorefresh */
+#define DMC_AR1		0x140000
+#define DMC_SDR_MR0	0x080032        /* MRS, CAS 3,  Burst Length 4 */
+#define DMC_SDR_MR1	0x180032
+#define DMC_DDR_MR0	0x080162
+#define DMC_DDR_MR1	0x180162
+#define DMC_mDDR_MR0	0x080032        /* CAS 3, Burst Length 4 */
+#define DMC_mDDR_MR1	0x180032
+#define DMC_mSDR_EMR0	0x0a0000        /* EMRS, DS:Full, PASR:Full Array */
+#define DMC_mSDR_EMR1	0x1a0000
+#define DMC_DDR_EMR0	0x090000
+#define DMC_DDR_EMR1	0x190000
+#define DMC_mDDR_EMR0	0x0a0000        /*  DS:Full, PASR:Full Array */
+#define DMC_mDDR_EMR1	0x1a0000
+
+/****************************************************************
+ Definitions for memory configuration
+ Set memory configuration
+	active_chips	 = 1'b0 (1 chip)
+	qos_master_chip  = 3'b000(ARID[3:0])
+	memory burst	 = 3'b010(burst 4)
+	stop_mem_clock	 = 1'b0(disable dynamical stop)
+	auto_power_down  = 1'b0(disable auto power-down mode)
+	power_down_prd	 = 6'b00_0000(0 cycle for auto power-down)
+	ap_bit		 = 1'b0 (bit position of auto-precharge is 10)
+	row_bits	 = 3'b010(# row address 13)
+	column_bits	 = 3'b010(# column address 10 )
+
+ Set user configuration
+	2'b10=SDRAM/mSDRAM, 2'b11=DDR, 2'b01=mDDR
+
+ Set chip select for chip [n]
+	 row bank control, bank address 0x3000_0000 ~ 0x37ff_ffff
+	 CHIP_[n]_CFG=0x30F8,  30: ADDR[31:24], F8: Mask[31:24]
+******************************************************************/
+
+/*
+ * Nand flash controller
+ */
+#define ELFIN_NAND_BASE		0x70200000
+
+#define NFCONF_OFFSET           0x00
+#define NFCONT_OFFSET           0x04
+#define NFCMMD_OFFSET           0x08
+#define NFADDR_OFFSET           0x0c
+#define NFDATA_OFFSET		0x10
+#define NFMECCDATA0_OFFSET      0x14
+#define NFMECCDATA1_OFFSET      0x18
+#define NFSECCDATA0_OFFSET      0x1c
+#define NFSBLK_OFFSET           0x20
+#define NFEBLK_OFFSET           0x24
+#define NFSTAT_OFFSET           0x28
+#define NFESTAT0_OFFSET         0x2c
+#define NFESTAT1_OFFSET         0x30
+#define NFMECC0_OFFSET          0x34
+#define NFMECC1_OFFSET          0x38
+#define NFSECC_OFFSET           0x3c
+#define NFMLCBITPT_OFFSET       0x40
+
+#define NFCONF			(ELFIN_NAND_BASE+NFCONF_OFFSET)
+#define NFCONT			(ELFIN_NAND_BASE+NFCONT_OFFSET)
+#define NFCMMD			(ELFIN_NAND_BASE+NFCMMD_OFFSET)
+#define NFADDR           	(ELFIN_NAND_BASE+NFADDR_OFFSET)
+#define NFDATA          	(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFMECCDATA0     	(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
+#define NFMECCDATA1     	(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
+#define NFSECCDATA0      	(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
+#define NFSBLK          	(ELFIN_NAND_BASE+NFSBLK_OFFSET)
+#define NFEBLK           	(ELFIN_NAND_BASE+NFEBLK_OFFSET)
+#define NFSTAT           	(ELFIN_NAND_BASE+NFSTAT_OFFSET)
+#define NFESTAT0         	(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
+#define NFESTAT1         	(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
+#define NFMECC0          	(ELFIN_NAND_BASE+NFMECC0_OFFSET)
+#define NFMECC1          	(ELFIN_NAND_BASE+NFMECC1_OFFSET)
+#define NFSECC           	(ELFIN_NAND_BASE+NFSECC_OFFSET)
+#define NFMLCBITPT           	(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
+
+#define NFCONF_REG		__REG(ELFIN_NAND_BASE+NFCONF_OFFSET)
+#define NFCONT_REG		__REG(ELFIN_NAND_BASE+NFCONT_OFFSET)
+#define NFCMD_REG		__REG(ELFIN_NAND_BASE+NFCMMD_OFFSET)
+#define NFADDR_REG           	__REG(ELFIN_NAND_BASE+NFADDR_OFFSET)
+#define NFDATA_REG          	__REG(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFDATA8_REG          	__REGb(ELFIN_NAND_BASE+NFDATA_OFFSET)
+#define NFMECCDATA0_REG     	__REG(ELFIN_NAND_BASE+NFMECCDATA0_OFFSET)
+#define NFMECCDATA1_REG     	__REG(ELFIN_NAND_BASE+NFMECCDATA1_OFFSET)
+#define NFSECCDATA0_REG      	__REG(ELFIN_NAND_BASE+NFSECCDATA0_OFFSET)
+#define NFSBLK_REG          	__REG(ELFIN_NAND_BASE+NFSBLK_OFFSET)
+#define NFEBLK_REG           	__REG(ELFIN_NAND_BASE+NFEBLK_OFFSET)
+#define NFSTAT_REG           	__REG(ELFIN_NAND_BASE+NFSTAT_OFFSET)
+#define NFESTAT0_REG         	__REG(ELFIN_NAND_BASE+NFESTAT0_OFFSET)
+#define NFESTAT1_REG         	__REG(ELFIN_NAND_BASE+NFESTAT1_OFFSET)
+#define NFMECC0_REG          	__REG(ELFIN_NAND_BASE+NFMECC0_OFFSET)
+#define NFMECC1_REG          	__REG(ELFIN_NAND_BASE+NFMECC1_OFFSET)
+#define NFSECC_REG           	__REG(ELFIN_NAND_BASE+NFSECC_OFFSET)
+#define NFMLCBITPT_REG         	__REG(ELFIN_NAND_BASE+NFMLCBITPT_OFFSET)
+
+#define NFCONF_ECC_4BIT		(1<<24)
+
+#define NFCONT_ECC_ENC		(1<<18)
+#define NFCONT_WP		(1<<16)
+#define NFCONT_MECCLOCK		(1<<7)
+#define NFCONT_SECCLOCK		(1<<6)
+#define NFCONT_INITMECC		(1<<5)
+#define NFCONT_INITSECC		(1<<4)
+#define NFCONT_INITECC		(NFCONT_INITMECC | NFCONT_INITSECC)
+#define NFCONT_CS_ALT		(1<<2)
+#define NFCONT_CS		(1<<1)
+#define NFCONT_ENABLE		(1<<0)
+
+#define NFSTAT_ECCENCDONE	(1<<7)
+#define NFSTAT_ECCDECDONE	(1<<6)
+#define NFSTAT_RnB		(1<<0)
+
+#define NFESTAT0_ECCBUSY	(1<<31)
+
+/*
+ * Interrupt
+ */
+#define ELFIN_VIC0_BASE_ADDR	0x71200000
+#define ELFIN_VIC1_BASE_ADDR	0x71300000
+#define oINTMOD			0x0C  /* VIC INT SELECT (IRQ or FIQ) */
+#define oINTUNMSK		0x10  /* VIC INT EN (Unmask by writing 1) */
+#define oINTMSK			0x14  /* VIC INT EN CLEAR (Mask by writing 1) */
+#define oINTSUBMSK		0x1C  /* VIC SOFT INT CLEAR */
+#define oVECTADDR		0xF00 /* VIC ADDRESS */
+
+/*
+ * Watchdog timer
+ */
+#define ELFIN_WATCHDOG_BASE	0x7E004000
+
+#define WTCON_REG		__REG(0x7E004004)
+#define WTDAT_REG		__REG(0x7E004008)
+#define WTCNT_REG		__REG(0x7E00400C)
+
+
+/*
+ * UART
+ */
+#define ELFIN_UART_BASE		0x7F005000
+
+#define ELFIN_UART0_OFFSET	0x0000
+#define ELFIN_UART1_OFFSET	0x0400
+#define ELFIN_UART2_OFFSET	0x0800
+
+#define ULCON_OFFSET		0x00
+#define UCON_OFFSET		0x04
+#define UFCON_OFFSET		0x08
+#define UMCON_OFFSET		0x0C
+#define UTRSTAT_OFFSET		0x10
+#define UERSTAT_OFFSET		0x14
+#define UFSTAT_OFFSET		0x18
+#define UMSTAT_OFFSET		0x1C
+#define UTXH_OFFSET		0x20
+#define URXH_OFFSET		0x24
+#define UBRDIV_OFFSET		0x28
+#define UDIVSLOT_OFFSET		0x2C
+#define UINTP_OFFSET		0x30
+#define UINTSP_OFFSET		0x34
+#define UINTM_OFFSET		0x38
+
+#define ULCON0_REG		__REG(0x7F005000)
+#define UCON0_REG		__REG(0x7F005004)
+#define UFCON0_REG		__REG(0x7F005008)
+#define UMCON0_REG		__REG(0x7F00500C)
+#define UTRSTAT0_REG		__REG(0x7F005010)
+#define UERSTAT0_REG		__REG(0x7F005014)
+#define UFSTAT0_REG		__REG(0x7F005018)
+#define UMSTAT0_REG		__REG(0x7F00501c)
+#define UTXH0_REG		__REG(0x7F005020)
+#define URXH0_REG		__REG(0x7F005024)
+#define UBRDIV0_REG		__REG(0x7F005028)
+#define UDIVSLOT0_REG		__REG(0x7F00502c)
+#define UINTP0_REG		__REG(0x7F005030)
+#define UINTSP0_REG		__REG(0x7F005034)
+#define UINTM0_REG		__REG(0x7F005038)
+
+#define ULCON1_REG		__REG(0x7F005400)
+#define UCON1_REG		__REG(0x7F005404)
+#define UFCON1_REG		__REG(0x7F005408)
+#define UMCON1_REG		__REG(0x7F00540C)
+#define UTRSTAT1_REG		__REG(0x7F005410)
+#define UERSTAT1_REG		__REG(0x7F005414)
+#define UFSTAT1_REG		__REG(0x7F005418)
+#define UMSTAT1_REG		__REG(0x7F00541c)
+#define UTXH1_REG		__REG(0x7F005420)
+#define URXH1_REG		__REG(0x7F005424)
+#define UBRDIV1_REG		__REG(0x7F005428)
+#define UDIVSLOT1_REG		__REG(0x7F00542c)
+#define UINTP1_REG		__REG(0x7F005430)
+#define UINTSP1_REG		__REG(0x7F005434)
+#define UINTM1_REG		__REG(0x7F005438)
+
+#define UTRSTAT_TX_EMPTY	(1 << 2)
+#define UTRSTAT_RX_READY	(1 << 0)
+#define UART_ERR_MASK		0xF
+
+/*
+ * PWM timer
+ */
+#define ELFIN_TIMER_BASE       0x7F006000
+
+#define TCFG0_REG              __REG(0x7F006000)
+#define TCFG1_REG              __REG(0x7F006004)
+#define TCON_REG               __REG(0x7F006008)
+#define TCNTB0_REG             __REG(0x7F00600c)
+#define TCMPB0_REG             __REG(0x7F006010)
+#define TCNTO0_REG             __REG(0x7F006014)
+#define TCNTB1_REG             __REG(0x7F006018)
+#define TCMPB1_REG             __REG(0x7F00601c)
+#define TCNTO1_REG             __REG(0x7F006020)
+#define TCNTB2_REG             __REG(0x7F006024)
+#define TCMPB2_REG             __REG(0x7F006028)
+#define TCNTO2_REG             __REG(0x7F00602c)
+#define TCNTB3_REG             __REG(0x7F006030)
+#define TCMPB3_REG             __REG(0x7F006034)
+#define TCNTO3_REG             __REG(0x7F006038)
+#define TCNTB4_REG             __REG(0x7F00603c)
+#define TCNTO4_REG             __REG(0x7F006040)
+
+/* Fields */
+#define fTCFG0_DZONE           Fld(8, 16) /* the dead zone length (= timer 0) */
+#define fTCFG0_PRE1            Fld(8, 8)  /* prescaler value for time 2,3,4 */
+#define fTCFG0_PRE0            Fld(8, 0)  /* prescaler value for time 0,1 */
+#define fTCFG1_MUX4            Fld(4, 16)
+/* bits */
+#define TCFG0_DZONE(x)         FInsrt((x), fTCFG0_DZONE)
+#define TCFG0_PRE1(x)          FInsrt((x), fTCFG0_PRE1)
+#define TCFG0_PRE0(x)          FInsrt((x), fTCFG0_PRE0)
+#define TCON_4_AUTO            (1 << 22)  /* auto reload on/off for Timer 4 */
+#define TCON_4_UPDATE          (1 << 21)  /* manual Update TCNTB4 */
+#define TCON_4_ONOFF           (1 << 20)  /* 0: Stop, 1: start Timer 4 */
+#define COUNT_4_ON             (TCON_4_ONOFF * 1)
+#define COUNT_4_OFF            (TCON_4_ONOFF * 0)
+#define TCON_3_AUTO            (1 << 19)  /* auto reload on/off for Timer 3 */
+#define TIMER3_ATLOAD_ON       (TCON_3_AUTO * 1)
+#define TIMER3_ATLAOD_OFF      FClrBit(TCON, TCON_3_AUTO)
+#define TCON_3_INVERT          (1 << 18)  /* 1: Inverter on for TOUT3 */
+#define TIMER3_IVT_ON          (TCON_3_INVERT * 1)
+#define TIMER3_IVT_OFF         (FClrBit(TCON, TCON_3_INVERT))
+#define TCON_3_MAN             (1 << 17)  /* manual Update TCNTB3,TCMPB3 */
+#define TIMER3_MANUP           (TCON_3_MAN*1)
+#define TIMER3_NOP             (FClrBit(TCON, TCON_3_MAN))
+#define TCON_3_ONOFF           (1 << 16)  /* 0: Stop, 1: start Timer 3 */
+#define TIMER3_ON              (TCON_3_ONOFF * 1)
+#define TIMER3_OFF             (FClrBit(TCON, TCON_3_ONOFF))
+
+#if defined(CONFIG_CLK_400_100_50)
+#define Startup_AMDIV		400
+#define Startup_MDIV		400
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_400_133_66)
+#define Startup_AMDIV		400
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_533_133_66)
+#define Startup_AMDIV		533
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#elif defined(CONFIG_CLK_667_133_66)
+#define Startup_AMDIV		667
+#define Startup_MDIV		533
+#define Startup_PDIV		6
+#define Startup_SDIV		1
+#endif
+
+#define	Startup_PCLKdiv		3
+#define Startup_HCLKx2div	1
+#define Startup_HCLKdiv		1
+#define Startup_MPLLdiv		1
+#define Startup_APLLdiv		0
+
+#define CLK_DIV_VAL	((Startup_PCLKdiv << 12) | (Startup_HCLKx2div << 9)| \
+	(Startup_HCLKdiv << 8) | (Startup_MPLLdiv<<4) | Startup_APLLdiv)
+#define MPLL_VAL	((1 << 31) | (Startup_MDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_MPLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_MDIV)
+
+#if defined(CONFIG_SYNC_MODE)
+#define APLL_VAL	((1 << 31) | (Startup_MDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_APLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_MDIV)
+#define Startup_HCLK	(Startup_MPLL / (Startup_HCLKx2div + 1) / \
+	(Startup_HCLKdiv + 1))
+#else
+#define APLL_VAL	((1 << 31) | (Startup_AMDIV << 16) | \
+	(Startup_PDIV << 8) | Startup_SDIV)
+#define Startup_APLL	(((CONFIG_SYS_CLK_FREQ >> Startup_SDIV) / \
+	Startup_PDIV) * Startup_AMDIV)
+#define Startup_HCLK	(Startup_MPLL / (Startup_HCLKx2div + 1) / \
+	(Startup_HCLKdiv + 1))
+#endif
+
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define DMC1_MEM_CFG	0x80010012	/* Chip1, Burst4, Row/Column bit */
+#define DMC1_MEM_CFG2	0xB45
+#define DMC1_CHIP0_CFG	0x150F8		/* 0x4000_0000 ~ 0x43ff_ffff (64MB) */
+#define DMC_DDR_32_CFG	0x0 		/* 32bit, DDR */
+
+/* Memory Parameters */
+/* DDR Parameters */
+#define DDR_tREFRESH		7800	/* ns */
+#define DDR_tRAS		45	/* ns (min: 45ns)*/
+#define DDR_tRC 		68	/* ns (min: 67.5ns)*/
+#define DDR_tRCD		23	/* ns (min: 22.5ns)*/
+#define DDR_tRFC		80	/* ns (min: 80ns)*/
+#define DDR_tRP 		23	/* ns (min: 22.5ns)*/
+#define DDR_tRRD		15	/* ns (min: 15ns)*/
+#define DDR_tWR 		15	/* ns (min: 15ns)*/
+#define DDR_tXSR		120	/* ns (min: 120ns)*/
+#define DDR_CASL		3	/* CAS Latency 3 */
+
+/*
+ * mDDR memory configuration
+ */
+#define DMC_DDR_BA_EMRS 	2
+#define DMC_DDR_MEM_CASLAT	3
+/* 6   Set Cas Latency to 3 */
+#define DMC_DDR_CAS_LATENCY	(DDR_CASL << 1)
+/* Min 0.75 ~ 1.25 */
+#define DMC_DDR_t_DQSS		1
+/* Min 2 tck */
+#define DMC_DDR_t_MRD		2
+/* 7, Min 45ns */
+#define DMC_DDR_t_RAS		(((Startup_HCLK/1000*DDR_tRAS)-1)/1000000+1)
+/* 10, Min 67.5ns */
+#define DMC_DDR_t_RC		(((Startup_HCLK/1000*DDR_tRC)-1)/1000000+1)
+/* 4,5(TRM), Min 22.5ns */
+#define DMC_DDR_t_RCD		(((Startup_HCLK/1000*DDR_tRCD)-1)/1000000+1)
+#define DMC_DDR_schedule_RCD	((DMC_DDR_t_RCD - 3) << 3)
+/* 11,18(TRM) Min 80ns */
+#define DMC_DDR_t_RFC		(((Startup_HCLK/1000*DDR_tRFC)-1)/1000000+1)
+#define DMC_DDR_schedule_RFC	((DMC_DDR_t_RFC - 3) << 5)
+/* 4, 5(TRM) Min 22.5ns */
+#define DMC_DDR_t_RP		(((Startup_HCLK/1000*DDR_tRP)-1)/1000000+1)
+#define DMC_DDR_schedule_RP	((DMC_DDR_t_RP - 3) << 3)
+/* 3, Min 15ns */
+#define DMC_DDR_t_RRD		(((Startup_HCLK/1000*DDR_tRRD)-1)/1000000+1)
+/* Min 15ns */
+#define DMC_DDR_t_WR		(((Startup_HCLK/1000*DDR_tWR)-1)/1000000+1)
+#define DMC_DDR_t_WTR		2
+/* 1tck + tIS(1.5ns) */
+#define DMC_DDR_t_XP		2
+/* 17, Min 120ns */
+#define DMC_DDR_t_XSR		(((Startup_HCLK/1000*DDR_tXSR)-1)/1000000+1)
+#define DMC_DDR_t_ESR		DMC_DDR_t_XSR
+/* TRM 2656 */
+#define DMC_DDR_REFRESH_PRD	(((Startup_HCLK/1000*DDR_tREFRESH)-1)/1000000)
+/* 2b01 : mDDR */
+#define DMC_DDR_USER_CONFIG	1
+
+#ifndef __ASSEMBLY__
+enum s3c64xx_uarts_nr {
+	S3C64XX_UART0,
+	S3C64XX_UART1,
+	S3C64XX_UART2,
+};
+
+#include "s3c64x0.h"
+
+static inline s3c64xx_uart *s3c64xx_get_base_uart(enum s3c64xx_uarts_nr nr)
+{
+	return (s3c64xx_uart *)(ELFIN_UART_BASE + (nr * 0x400));
+}
+#endif
+
+#endif /*__S3C6400_H__*/
diff --git a/include/s3c64x0.h b/include/s3c64x0.h
new file mode 100644
index 0000000..ba6802a
--- /dev/null
+++ b/include/s3c64x0.h
@@ -0,0 +1,92 @@
+/*
+ * (C) Copyright 2003
+ * David M??ller ELSOFT AG Switzerland. d.mueller at elsoft.ch
+ *
+ * (C) Copyright 2008
+ * Guennadi Liakhovetki, DENX Software Engineering, <lg@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
+ */
+
+/************************************************
+ * NAME	    : S3C64XX.h
+ * Version  : 31.3.2003
+ *
+ * common stuff for SAMSUNG S3C64XX SoC
+ ************************************************/
+
+#ifndef __S3C64XX_H__
+#define __S3C64XX_H__
+
+#if defined(CONFIG_SYNC_MODE) && defined(CONFIG_S3C6400)
+#error CONFIG_SYNC_MODE unavailable on S3C6400, please, fix your configuration!
+#endif
+
+typedef vu_char		S3C64XX_REG8;
+typedef vu_short	S3C64XX_REG16;
+typedef vu_long		S3C64XX_REG32;
+
+/* UART (see manual chapter 11) */
+typedef struct {
+	S3C64XX_REG32	ULCON;
+	S3C64XX_REG32	UCON;
+	S3C64XX_REG32	UFCON;
+	S3C64XX_REG32	UMCON;
+	S3C64XX_REG32	UTRSTAT;
+	S3C64XX_REG32	UERSTAT;
+	S3C64XX_REG32	UFSTAT;
+	S3C64XX_REG32	UMSTAT;
+#ifdef __BIG_ENDIAN
+	S3C64XX_REG8	res1[3];
+	S3C64XX_REG8	UTXH;
+	S3C64XX_REG8	res2[3];
+	S3C64XX_REG8	URXH;
+#else /* Little Endian */
+	S3C64XX_REG8	UTXH;
+	S3C64XX_REG8	res1[3];
+	S3C64XX_REG8	URXH;
+	S3C64XX_REG8	res2[3];
+#endif
+	S3C64XX_REG32	UBRDIV;
+#ifdef __BIG_ENDIAN
+	S3C64XX_REG8	res3[2];
+	S3C64XX_REG16	UDIVSLOT;
+#else
+	S3C64XX_REG16	UDIVSLOT;
+	S3C64XX_REG8	res3[2];
+#endif
+} /*__attribute__((__packed__))*/ s3c64xx_uart;
+
+/* PWM TIMER (see manual chapter 10) */
+typedef struct {
+	S3C64XX_REG32	TCNTB;
+	S3C64XX_REG32	TCMPB;
+	S3C64XX_REG32	TCNTO;
+} /*__attribute__((__packed__))*/ s3c64xx_timer;
+
+typedef struct {
+	S3C64XX_REG32	TCFG0;
+	S3C64XX_REG32	TCFG1;
+	S3C64XX_REG32	TCON;
+	s3c64xx_timer	ch[4];
+	S3C64XX_REG32	TCNTB4;
+	S3C64XX_REG32	TCNTO4;
+} /*__attribute__((__packed__))*/ s3c64xx_timers;
+
+#endif /*__S3C64XX_H__*/
-- 
1.5.4

^ permalink raw reply related	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 7/7 v3] ARM: Add support for S3C6400 based SMDK6400 board
  2008-08-04 12:46           ` [U-Boot-Users] [PATCH 7/7 v3] ARM: Add support for S3C6400 based SMDK6400 board Guennadi Liakhovetski
@ 2008-08-04 20:10             ` Guennadi Liakhovetski
  0 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 20:10 UTC (permalink / raw)
  To: u-boot

This is just to apologise for not CC-ing the ARM-maintainer in the 
original post. I did forward him the patch afterwards, sorry.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 4/7 v3] USB: Add support for OHCI controller on s3c6400
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 4/7 v3] USB: Add support for OHCI controller on s3c6400 Guennadi Liakhovetski
@ 2008-08-04 21:08             ` Jean-Christophe PLAGNIOL-VILLARD
  2008-08-04 22:04               ` Guennadi Liakhovetski
  0 siblings, 1 reply; 36+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2008-08-04 21:08 UTC (permalink / raw)
  To: u-boot

 diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c
> index fd60edb..0bfa4d7 100644
> --- a/drivers/usb/usb_ohci.c
> +++ b/drivers/usb/usb_ohci.c
> @@ -69,6 +69,7 @@
>  #if defined(CONFIG_ARM920T) || \
>      defined(CONFIG_S3C2400) || \
>      defined(CONFIG_S3C2410) || \
> +    defined(CONFIG_S3C6400) || \
>      defined(CONFIG_440EP) || \
>      defined(CONFIG_PCI_OHCI) || \
>      defined(CONFIG_MPC5200) || \

Can we start to avoid 10km if defined in the code?

Maybe we can find an other way do it?

Best Regards,
J.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver Guennadi Liakhovetski
@ 2008-08-04 21:19             ` Jean-Christophe PLAGNIOL-VILLARD
  2008-08-04 22:08               ` Guennadi Liakhovetski
  0 siblings, 1 reply; 36+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2008-08-04 21:19 UTC (permalink / raw)
  To: u-boot

On 14:45 Mon 04 Aug     , Guennadi Liakhovetski wrote:
> Ported from u-boot-1.1.6 driver by Samsung.
> 
> Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
> ---
> 
> Also added my copyright to the driver.
> 
>  drivers/serial/Makefile  |    1 +
>  drivers/serial/s3c64xx.c |  189 ++++++++++++++++++++++++++++++++++++++++++++++
>  2 files changed, 190 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/serial/s3c64xx.c
> 
> diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> index c9e797e..2a11ae5 100644
> --- a/drivers/serial/Makefile
> +++ b/drivers/serial/Makefile
> @@ -30,6 +30,7 @@ COBJS-y += mcfuart.o
>  COBJS-y += ns9750_serial.o
>  COBJS-y += ns16550.o
>  COBJS-y += s3c4510b_uart.o
> +COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
>  COBJS-y += serial.o
>  COBJS-y += serial_max3100.o
>  COBJS-y += serial_pl010.o
I've send a patch that break it.

Could you rebase it on the current Wolfgang tree HEAD?

> diff --git a/drivers/serial/s3c64xx.c b/drivers/serial/s3c64xx.c
> new file mode 100644
> index 0000000..9580909
> --- /dev/null
> +++ b/drivers/serial/s3c64xx.c
> @@ -0,0 +1,189 @@
> +/*
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering, <gj@denx.de>
> + *
> + * (C) Copyright 2008
> + * Guennadi Liakhovetki, DENX Software Engineering, <lg@denx.de>
> + *
> + * 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 <s3c6400.h>
> +
> +#ifdef CONFIG_SERIAL1
> +#define UART_NR	S3C64XX_UART0
> +
> +#elif defined(CONFIG_SERIAL2)
> +#define UART_NR	S3C64XX_UART1
> +
> +#elif defined(CONFIG_SERIAL3)
> +#define UART_NR	S3C64XX_UART2
> +
> +#else
> +#error "Bad: you didn't configure serial ..."
> +#endif
> +
> +#define barrier() asm volatile("" ::: "memory")
> +
> +/* See table in 31.6.11 */
> +static const int udivslot[] = {
> +	0,
> +	0x0080,
> +	0x0808,
> +	0x0888,
> +	0x2222,
> +	0x4924,
> +	0x4a52,
> +	0x54aa,
> +	0x5555,
> +	0xd555,
> +	0xd5d5,
> +	0xddd5,
> +	0xdddd,
> +	0xdfdd,
> +	0xdfdf,
> +	0xffdf,
> +};
Can we have something more readable?
> +
> +void serial_setbrg(void)
> +{
> +	DECLARE_GLOBAL_DATA_PTR;
> +	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
> +	u32 reg, pclk_ratio = get_PCLK() / gd->baudrate;
why not
	u32 reg;
	u32 pclk_ratio = get_PCLK() / gd->baudrate;
> +	int i;
> +
> +	/* PCLK / (16 * baudrate) - 1 */
> +	reg = pclk_ratio / 16 - 1;
> +	i = pclk_ratio - (reg + 1) * 16;
=>
	i = pclk_ratio - (pclk_ratio / 16 - 1 + 1) * 16;
=>
	i = pclk_ratio - (pclk_ratio / 16 ) * 16;
=>
	i = pclk_ratio - pclk_ratio;
=>
	i = 0;
> +
> +	uart->UBRDIV = reg;
> +	uart->UDIVSLOT = udivslot[i];
base on the cose
	uart->UDIVSLOT = udivslot[0];

> +
> +	for (i = 0; i < 100; i++)
> +		barrier();
> +}
> +
> +#ifdef CONFIG_HWFLOW
> +static int hwflow;		/* turned off by default */
why not?
static int hwflow = 0;		/* turned off by default */
> +int hwflow_onoff(int on)
> +{
> +	switch (on) {
> +	case 1:
> +		hwflow = 1;	/* turn on */
> +		break;
> +	case -1:
> +		hwflow = 0;	/* turn off */
> +		break;
> +	}
> +	return hwflow;
> +}
> +#endif
> +
> +#ifdef CONFIG_MODEM_SUPPORT
> +static int be_quiet;
why not?
static int be_quiet = 0;
> +void disable_putc(void)
> +{
> +	be_quiet = 1;
> +}
> +
> +void enable_putc(void)
> +{
> +	be_quiet = 0;
> +}
> +#endif
> +
Best Regards,

J.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 4/7 v3] USB: Add support for OHCI controller on s3c6400
  2008-08-04 21:08             ` Jean-Christophe PLAGNIOL-VILLARD
@ 2008-08-04 22:04               ` Guennadi Liakhovetski
  0 siblings, 0 replies; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 22:04 UTC (permalink / raw)
  To: u-boot

On Mon, 4 Aug 2008, Jean-Christophe PLAGNIOL-VILLARD wrote:

>  diff --git a/drivers/usb/usb_ohci.c b/drivers/usb/usb_ohci.c
> > index fd60edb..0bfa4d7 100644
> > --- a/drivers/usb/usb_ohci.c
> > +++ b/drivers/usb/usb_ohci.c
> > @@ -69,6 +69,7 @@
> >  #if defined(CONFIG_ARM920T) || \
> >      defined(CONFIG_S3C2400) || \
> >      defined(CONFIG_S3C2410) || \
> > +    defined(CONFIG_S3C6400) || \
> >      defined(CONFIG_440EP) || \
> >      defined(CONFIG_PCI_OHCI) || \
> >      defined(CONFIG_MPC5200) || \
> 
> Can we start to avoid 10km if defined in the code?
> 
> Maybe we can find an other way do it?

Sure, I think, the USB-custodian will be glad to see patches.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver
  2008-08-04 21:19             ` Jean-Christophe PLAGNIOL-VILLARD
@ 2008-08-04 22:08               ` Guennadi Liakhovetski
  2008-08-04 22:52                 ` Wolfgang Denk
  0 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-04 22:08 UTC (permalink / raw)
  To: u-boot

On Mon, 4 Aug 2008, Jean-Christophe PLAGNIOL-VILLARD wrote:

> On 14:45 Mon 04 Aug     , Guennadi Liakhovetski wrote:
> > Ported from u-boot-1.1.6 driver by Samsung.
> > 
> > Signed-off-by: Guennadi Liakhovetski <lg@denx.de>
> > ---
> > 
> > Also added my copyright to the driver.
> > 
> >  drivers/serial/Makefile  |    1 +
> >  drivers/serial/s3c64xx.c |  189 ++++++++++++++++++++++++++++++++++++++++++++++
> >  2 files changed, 190 insertions(+), 0 deletions(-)
> >  create mode 100644 drivers/serial/s3c64xx.c
> > 
> > diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
> > index c9e797e..2a11ae5 100644
> > --- a/drivers/serial/Makefile
> > +++ b/drivers/serial/Makefile
> > @@ -30,6 +30,7 @@ COBJS-y += mcfuart.o
> >  COBJS-y += ns9750_serial.o
> >  COBJS-y += ns16550.o
> >  COBJS-y += s3c4510b_uart.o
> > +COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
> >  COBJS-y += serial.o
> >  COBJS-y += serial_max3100.o
> >  COBJS-y += serial_pl010.o
> I've send a patch that break it.
> 
> Could you rebase it on the current Wolfgang tree HEAD?

Ok, will have a look.

> > +/* See table in 31.6.11 */
> > +static const int udivslot[] = {
> > +	0,
> > +	0x0080,
> > +	0x0808,
> > +	0x0888,
> > +	0x2222,
> > +	0x4924,
> > +	0x4a52,
> > +	0x54aa,
> > +	0x5555,
> > +	0xd555,
> > +	0xd5d5,
> > +	0xddd5,
> > +	0xdddd,
> > +	0xdfdd,
> > +	0xdfdf,
> > +	0xffdf,
> > +};
> Can we have something more readable?

No. This are "recommended values" as mentioned in the comment to the table 
referenced above.

> > +void serial_setbrg(void)
> > +{
> > +	DECLARE_GLOBAL_DATA_PTR;
> > +	s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
> > +	u32 reg, pclk_ratio = get_PCLK() / gd->baudrate;
> why not
> 	u32 reg;
> 	u32 pclk_ratio = get_PCLK() / gd->baudrate;

There is more than one way to do it.

> > +	int i;
> > +
> > +	/* PCLK / (16 * baudrate) - 1 */
> > +	reg = pclk_ratio / 16 - 1;
> > +	i = pclk_ratio - (reg + 1) * 16;
> =>
> 	i = pclk_ratio - (pclk_ratio / 16 - 1 + 1) * 16;
> =>
> 	i = pclk_ratio - (pclk_ratio / 16 ) * 16;
> =>
> 	i = pclk_ratio - pclk_ratio;
> =>
> 	i = 0;

Please, think again. This is integer arithmetics, not analysis.

> > +
> > +	uart->UBRDIV = reg;
> > +	uart->UDIVSLOT = udivslot[i];
> base on the cose
> 	uart->UDIVSLOT = udivslot[0];

See above.

> > +static int hwflow;		/* turned off by default */
> why not?
> static int hwflow = 0;		/* turned off by default */

Because static are always initialised to 0, and, in fact, checkpatch.pl 
produces warnings on these, and rightfully so.

> > +static int be_quiet;
> why not?
> static int be_quiet = 0;

See above.

Thanks for your comments
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
  2008-08-04 12:45           ` [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead Guennadi Liakhovetski
@ 2008-08-04 22:28             ` Scott Wood
  2008-08-05 13:08               ` Guennadi Liakhovetski
  0 siblings, 1 reply; 36+ messages in thread
From: Scott Wood @ 2008-08-04 22:28 UTC (permalink / raw)
  To: u-boot

On Mon, Aug 04, 2008 at 02:45:33PM +0200, Guennadi Liakhovetski wrote:
> I _think_ this should work with all NAND chips. Otherwise we might have to 
> introduce a configuration variable.

Which small-page NAND chips can't handle READOOB?  On large page devices,
nand_command changes it to READ0.

That said, doing it all at once could result in smaller, faster, and
simpler code.

> @@ -150,8 +135,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
>  	u_char *ecc_code;
>  	u_char *oob_data;
>  	int i;
> -	int eccsize = CFG_NAND_ECCSIZE;
> -	int eccbytes = CFG_NAND_ECCBYTES;

Any particular reason for this change?  It's more readable as is, IMHO.

> @@ -195,6 +180,7 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst)
>  	int block;
>  	int blockcopy_count;
>  	int page;
> +	unsigned read = 0;

"unsigned int", please.

> +		int badblock = 0;
> +		for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) {
> +			nand_read_page(mtd, block, page, dst);
> +			if ((!page
> +#ifdef CFG_NAND_BBT_2NDPAGE
> +			     || page == 1
> +#endif

Please use page == 0 rather than !page when checking for an actual value
of zero as opposed to a zero that means "not valid" or similar.

> +				    ) && dst[CFG_NAND_PAGE_SIZE] != 0xff) {
> +				badblock = 1;
> +				break;
>  			}
> +			/* Overwrite skipped pages */
> +			if (read >= offs)
> +				dst += CFG_NAND_PAGE_SIZE;
> +			read += CFG_NAND_PAGE_SIZE;
> +		}

I don't follow the logic here -- you're discarding a number of good
blocks equal to the offset?  That might make sense if we were starting at
block zero, and defining the offset as not including any bad blocks
before the image -- but the first block we read is at the start of the
image, not the start of flash.

> @@ -241,12 +239,18 @@ void nand_boot(void)
>  	nand_chip.dev_ready = NULL;	/* preset to NULL */
>  	board_nand_init(&nand_chip);
>  
> +	if (nand_chip.select_chip)
> +		nand_chip.select_chip(&nand_info, 0);
> +
>  	/*
>  	 * Load U-Boot image from NAND into RAM
>  	 */
>  	ret = nand_load(&nand_info, CFG_NAND_U_BOOT_OFFS, CFG_NAND_U_BOOT_SIZE,
>  			(uchar *)CFG_NAND_U_BOOT_DST);
>  
> +	if (nand_chip.select_chip)
> +		nand_chip.select_chip(&nand_info, -1);
> +

This seems like an unrelated change, that wasn't described in the
changelog.

-Scott

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 6/7 v3] NAND: add NAND driver for s3c64xx
  2008-08-04 12:46           ` [U-Boot-Users] [PATCH 6/7 v3] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
@ 2008-08-04 22:38             ` Scott Wood
  0 siblings, 0 replies; 36+ messages in thread
From: Scott Wood @ 2008-08-04 22:38 UTC (permalink / raw)
  To: u-boot

On Mon, Aug 04, 2008 at 02:46:15PM +0200, Guennadi Liakhovetski wrote:
> +#ifdef CONFIG_NAND_SPL
> +static u_char nand_read_byte(struct mtd_info *mtd)
> +{
> +	struct nand_chip *this = mtd->priv;
> +	return readb(this->IO_ADDR_R);
> +}
> +
> +static void nand_write_byte(struct mtd_info *mtd, u_char byte)
> +{
> +	struct nand_chip *this = mtd->priv;
> +	writeb(byte, this->IO_ADDR_W);
> +}
> +
> +static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
> +{
> +	int i;
> +	struct nand_chip *this = mtd->priv;
> +
> +	for (i = 0; i < len; i++)
> +		buf[i] = readb(this->IO_ADDR_R);
> +}
> +#endif

We should probably move this under nand_spl/, and let boards select it
if they need it.

> +/*
> + * Hardware specific access to control-lines function
> + * Written by jsgood
> + */
> +static void s3c_nand_hwcontrol(struct mtd_info *mtd, int cmd)
> +{
> +	struct nand_chip *this = mtd->priv;
> +
> +	switch (cmd) {
> +	case NAND_CTL_SETCLE:
> +		this->IO_ADDR_W = (void __iomem *)NFCMMD;
> +		break;
> +	case NAND_CTL_CLRCLE:
> +		this->IO_ADDR_W = (void __iomem *)NFDATA;
> +		break;
> +	case NAND_CTL_SETALE:
> +		this->IO_ADDR_W = (void __iomem *)NFADDR;
> +		break;
> +	case NAND_CTL_CLRALE:
> +		this->IO_ADDR_W = (void __iomem *)NFDATA;
> +		break;
> +	case NAND_CTL_SETNCE:
> +		s3c_nand_select_chip(mtd, 0);
> +		break;
> +	case NAND_CTL_CLRNCE:
> +		s3c_nand_select_chip(mtd, -1);
> +		break;
> +	}
> +}

This interface has changed in u-boot-nand-flash/testing.  Can you rebase
against it?

-Scott

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver
  2008-08-04 22:08               ` Guennadi Liakhovetski
@ 2008-08-04 22:52                 ` Wolfgang Denk
  0 siblings, 0 replies; 36+ messages in thread
From: Wolfgang Denk @ 2008-08-04 22:52 UTC (permalink / raw)
  To: u-boot

In message <Pine.LNX.4.64.0808050004180.10557@axis700.grange> you wrote:
> 
> > > +/* See table in 31.6.11 */
> > > +static const int udivslot[] = {
> > > +	0,
> > > +	0x0080,
> > > +	0x0808,
> > > +	0x0888,
> > > +	0x2222,
> > > +	0x4924,
> > > +	0x4a52,
> > > +	0x54aa,
> > > +	0x5555,
> > > +	0xd555,
> > > +	0xd5d5,
> > > +	0xddd5,
> > > +	0xdddd,
> > > +	0xdfdd,
> > > +	0xdfdf,
> > > +	0xffdf,
> > > +};
> > Can we have something more readable?
> 
> No. This are "recommended values" as mentioned in the comment to the table 
> referenced above.

Bout perhaps you could add some documentation what  all  these  magic
numbers  mean? Of course we can all download the documetnation, study
it for hours and finally uinderstand this, too  -  but  it  would  be
nicer if you could save us this effort.

> > > +	u32 reg, pclk_ratio = get_PCLK() / gd->baudrate;
> > why not
> > 	u32 reg;
> > 	u32 pclk_ratio = get_PCLK() / gd->baudrate;
> 
> There is more than one way to do it.

Indeed. But the one that is better readable is preferred.

> > > +	/* PCLK / (16 * baudrate) - 1 */
> > > +	reg = pclk_ratio / 16 - 1;
> > > +	i = pclk_ratio - (reg + 1) * 16;
> > =>
> > 	i = pclk_ratio - (pclk_ratio / 16 - 1 + 1) * 16;
> > =>
> > 	i = pclk_ratio - (pclk_ratio / 16 ) * 16;
> > =>
> > 	i = pclk_ratio - pclk_ratio;
> > =>
> > 	i = 0;
> 
> Please, think again. This is integer arithmetics, not analysis.

So perhaps you want to elucidate your code in a comment?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
grep me no patterns and I'll tell you no lines.

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
  2008-08-04 22:28             ` Scott Wood
@ 2008-08-05 13:08               ` Guennadi Liakhovetski
  2008-08-05 15:01                 ` Scott Wood
  0 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-05 13:08 UTC (permalink / raw)
  To: u-boot

On Mon, 4 Aug 2008, Scott Wood wrote:

> On Mon, Aug 04, 2008 at 02:45:33PM +0200, Guennadi Liakhovetski wrote:
> > I _think_ this should work with all NAND chips. Otherwise we might have to 
> > introduce a configuration variable.
> 
> Which small-page NAND chips can't handle READOOB?  On large page devices,
> nand_command changes it to READ0.

It's a large-page device. And, as far as I understand the datasheet, to 
read data at arbitrary offset in a page, you first have to issue a READ 
PAGE (READ0) for _the_ _whole_ page, then you can use RANDOM DATA READ to 
read arbitrary data within this page. Whereas, the driver attempts to use 
READ0 to read the bad-block marker directly, which doesn't work with this 
chip. At least this is my understanding.

> That said, doing it all at once could result in smaller, faster, and
> simpler code.
> 
> > @@ -150,8 +135,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
> >  	u_char *ecc_code;
> >  	u_char *oob_data;
> >  	int i;
> > -	int eccsize = CFG_NAND_ECCSIZE;
> > -	int eccbytes = CFG_NAND_ECCBYTES;
> 
> Any particular reason for this change?  It's more readable as is, IMHO.

Acually, it was to improve readability:-) First, this way you can easier 
grep. Secondly, when I see an assignment to a _variable_, I expect, that 
this variable's value can indeed _vary_. So, it makes extra work looking 
through the code and verifying what other values this variable takes. 
Thus, at the very least I would add "const" to the definition. And, I do 
think using constants directly makes it clearer...

> > @@ -195,6 +180,7 @@ static int nand_load(struct mtd_info *mtd, int offs, int uboot_size, uchar *dst)
> >  	int block;
> >  	int blockcopy_count;
> >  	int page;
> > +	unsigned read = 0;
> 
> "unsigned int", please.

Ok...

> > +		int badblock = 0;
> > +		for (page = 0; page < CFG_NAND_PAGE_COUNT; page++) {
> > +			nand_read_page(mtd, block, page, dst);
> > +			if ((!page
> > +#ifdef CFG_NAND_BBT_2NDPAGE
> > +			     || page == 1
> > +#endif
> 
> Please use page == 0 rather than !page when checking for an actual value
> of zero as opposed to a zero that means "not valid" or similar.

Ok...

> > +				    ) && dst[CFG_NAND_PAGE_SIZE] != 0xff) {
> > +				badblock = 1;
> > +				break;
> >  			}
> > +			/* Overwrite skipped pages */
> > +			if (read >= offs)
> > +				dst += CFG_NAND_PAGE_SIZE;
> > +			read += CFG_NAND_PAGE_SIZE;
> > +		}
> 
> I don't follow the logic here -- you're discarding a number of good
> blocks equal to the offset?  That might make sense if we were starting at
> block zero, and defining the offset as not including any bad blocks
> before the image -- but the first block we read is at the start of the
> image, not the start of flash.

Right, that's a bug. Hope, it's fixed now.

> > @@ -241,12 +239,18 @@ void nand_boot(void)
> >  	nand_chip.dev_ready = NULL;	/* preset to NULL */
> >  	board_nand_init(&nand_chip);
> >  
> > +	if (nand_chip.select_chip)
> > +		nand_chip.select_chip(&nand_info, 0);
> > +
> >  	/*
> >  	 * Load U-Boot image from NAND into RAM
> >  	 */
> >  	ret = nand_load(&nand_info, CFG_NAND_U_BOOT_OFFS, CFG_NAND_U_BOOT_SIZE,
> >  			(uchar *)CFG_NAND_U_BOOT_DST);
> >  
> > +	if (nand_chip.select_chip)
> > +		nand_chip.select_chip(&nand_info, -1);
> > +
> 
> This seems like an unrelated change, that wasn't described in the
> changelog.

Ok, will describe in the changelog.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
  2008-08-05 13:08               ` Guennadi Liakhovetski
@ 2008-08-05 15:01                 ` Scott Wood
  2008-08-05 15:25                   ` Guennadi Liakhovetski
  0 siblings, 1 reply; 36+ messages in thread
From: Scott Wood @ 2008-08-05 15:01 UTC (permalink / raw)
  To: u-boot

On Tue, Aug 05, 2008 at 03:08:04PM +0200, Guennadi Liakhovetski wrote:
> It's a large-page device. And, as far as I understand the datasheet, to 
> read data at arbitrary offset in a page, you first have to issue a READ 
> PAGE (READ0) for _the_ _whole_ page, then you can use RANDOM DATA READ to 
> read arbitrary data within this page. Whereas, the driver attempts to use 
> READ0 to read the bad-block marker directly, which doesn't work with this 
> chip. At least this is my understanding.

Are you saying that your NAND chip can't read the OOB by issuing READ0
with the appropriate column address?  Which chip is this, and where can I
find a manual?

> > > @@ -150,8 +135,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
> > >  	u_char *ecc_code;
> > >  	u_char *oob_data;
> > >  	int i;
> > > -	int eccsize = CFG_NAND_ECCSIZE;
> > > -	int eccbytes = CFG_NAND_ECCBYTES;
> > 
> > Any particular reason for this change?  It's more readable as is, IMHO.
> 
> Acually, it was to improve readability:-) First, this way you can easier 
> grep.

Grep will find the initialization.

> Secondly, when I see an assignment to a _variable_, I expect, that this
> variable's value can indeed _vary_. So, it makes extra work looking
> through the code and verifying what other values this variable takes. 
> Thus, at the very least I would add "const" to the definition. And, I
> do think using constants directly makes it clearer...

It replaces a short lower-case name with a longer all-caps name that
forces line breaks.  I'm fine with adding "const".

-Scott

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
  2008-08-05 15:01                 ` Scott Wood
@ 2008-08-05 15:25                   ` Guennadi Liakhovetski
  2008-08-05 15:37                     ` Scott Wood
  0 siblings, 1 reply; 36+ messages in thread
From: Guennadi Liakhovetski @ 2008-08-05 15:25 UTC (permalink / raw)
  To: u-boot

On Tue, 5 Aug 2008, Scott Wood wrote:

> On Tue, Aug 05, 2008 at 03:08:04PM +0200, Guennadi Liakhovetski wrote:
> > It's a large-page device. And, as far as I understand the datasheet, to 
> > read data at arbitrary offset in a page, you first have to issue a READ 
> > PAGE (READ0) for _the_ _whole_ page, then you can use RANDOM DATA READ to 
> > read arbitrary data within this page. Whereas, the driver attempts to use 
> > READ0 to read the bad-block marker directly, which doesn't work with this 
> > chip. At least this is my understanding.
> 
> Are you saying that your NAND chip can't read the OOB by issuing READ0
> with the appropriate column address?  Which chip is this, and where can I
> find a manual?

At least, this is how I understood it, I might be wrong though:

http://download.micron.com/pdf/datasheets/flash/nand/2_4_8gb_nand_m49a.pdf

pages 21, 22.

> > > > @@ -150,8 +135,6 @@ static int nand_read_page(struct mtd_info *mtd, int block, int page, uchar *dst)
> > > >  	u_char *ecc_code;
> > > >  	u_char *oob_data;
> > > >  	int i;
> > > > -	int eccsize = CFG_NAND_ECCSIZE;
> > > > -	int eccbytes = CFG_NAND_ECCBYTES;
> > > 
> > > Any particular reason for this change?  It's more readable as is, IMHO.
> > 
> > Acually, it was to improve readability:-) First, this way you can easier 
> > grep.
> 
> Grep will find the initialization.
> 
> > Secondly, when I see an assignment to a _variable_, I expect, that this
> > variable's value can indeed _vary_. So, it makes extra work looking
> > through the code and verifying what other values this variable takes. 
> > Thus, at the very least I would add "const" to the definition. And, I
> > do think using constants directly makes it clearer...
> 
> It replaces a short lower-case name with a longer all-caps name that
> forces line breaks.  I'm fine with adding "const".

Ok...

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.

DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office at denx.de

^ permalink raw reply	[flat|nested] 36+ messages in thread

* [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead
  2008-08-05 15:25                   ` Guennadi Liakhovetski
@ 2008-08-05 15:37                     ` Scott Wood
  0 siblings, 0 replies; 36+ messages in thread
From: Scott Wood @ 2008-08-05 15:37 UTC (permalink / raw)
  To: u-boot

Guennadi Liakhovetski wrote:
> On Tue, 5 Aug 2008, Scott Wood wrote:
>> Are you saying that your NAND chip can't read the OOB by issuing READ0
>> with the appropriate column address?  Which chip is this, and where can I
>> find a manual?
> 
> At least, this is how I understood it, I might be wrong though:
> 
> http://download.micron.com/pdf/datasheets/flash/nand/2_4_8gb_nand_m49a.pdf
> 
> pages 21, 22.

The READ0 command says, "Starting from the initial column address and 
going to the end of the page, read the data by repeatedly pulsing RE# at 
the maximum tRC rate (see Figure 14)."  That looks normal...  have you 
tried it?

IIUC, the "complete page of data" refers to the transfer from the NAND 
storage to the chip's page buffer, not to the transfer from the buffer 
to the CPU.

-Scott

^ permalink raw reply	[flat|nested] 36+ messages in thread

end of thread, other threads:[~2008-08-05 15:37 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-31 10:54 [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
2008-07-31 14:24 ` Wolfgang Denk
2008-08-01 11:02   ` Guennadi Liakhovetski
2008-08-01 12:28     ` Wolfgang Denk
2008-08-01 13:30       ` [U-Boot-Users] several messages Guennadi Liakhovetski
2008-08-04 10:42       ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Guennadi Liakhovetski
2008-08-04 10:42         ` [U-Boot-Users] [PATCH 1/7 v2] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
2008-08-04 10:42         ` [U-Boot-Users] [PATCH 2/7 v2] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead Guennadi Liakhovetski
2008-08-04 10:43         ` [U-Boot-Users] [PATCH 3/7 v2] ARM: Add arm1176 core with s3c6400 SoC Guennadi Liakhovetski
2008-08-04 10:43         ` [U-Boot-Users] [PATCH 4/7 v2] USB: Add support for OHCI controller on s3c6400 Guennadi Liakhovetski
2008-08-04 10:43         ` [U-Boot-Users] [PATCH 5/7 v2] serial: add s3c64xx serial driver Guennadi Liakhovetski
2008-08-04 10:43         ` [U-Boot-Users] [PATCH 6/7 v2] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
2008-08-04 10:43         ` [U-Boot-Users] [PATCH 7/7 v2] ARM: Add support for S3C6400 based SMDK6400 board Guennadi Liakhovetski
2008-08-04 11:00         ` [U-Boot-Users] [PATCH 0/7 v2] SMDK6400 support Wolfgang Denk
2008-08-04 12:44         ` [U-Boot-Users] [PATCH 0/7 v3] " Guennadi Liakhovetski
2008-08-04 12:44           ` [U-Boot-Users] [PATCH 1/7 v3] Add definition for the AM29LV800BB AMD NOR-flash Guennadi Liakhovetski
2008-08-04 12:45           ` [U-Boot-Users] [PATCH 2/7 v3] NAND_CMD_READOOB is not supported by all chips, read OOB with the page instead Guennadi Liakhovetski
2008-08-04 22:28             ` Scott Wood
2008-08-05 13:08               ` Guennadi Liakhovetski
2008-08-05 15:01                 ` Scott Wood
2008-08-05 15:25                   ` Guennadi Liakhovetski
2008-08-05 15:37                     ` Scott Wood
2008-08-04 12:45           ` [U-Boot-Users] [PATCH 3/7 v3] ARM: Add arm1176 core with s3c6400 SoC Guennadi Liakhovetski
2008-08-04 20:06             ` [U-Boot-Users] [PATCH 3/7 v4] " Guennadi Liakhovetski
2008-08-04 12:45           ` [U-Boot-Users] [PATCH 4/7 v3] USB: Add support for OHCI controller on s3c6400 Guennadi Liakhovetski
2008-08-04 21:08             ` Jean-Christophe PLAGNIOL-VILLARD
2008-08-04 22:04               ` Guennadi Liakhovetski
2008-08-04 12:45           ` [U-Boot-Users] [PATCH 5/7 v3] serial: add s3c64xx serial driver Guennadi Liakhovetski
2008-08-04 21:19             ` Jean-Christophe PLAGNIOL-VILLARD
2008-08-04 22:08               ` Guennadi Liakhovetski
2008-08-04 22:52                 ` Wolfgang Denk
2008-08-04 12:46           ` [U-Boot-Users] [PATCH 6/7 v3] NAND: add NAND driver for s3c64xx Guennadi Liakhovetski
2008-08-04 22:38             ` Scott Wood
2008-08-04 12:46           ` [U-Boot-Users] [PATCH 7/7 v3] ARM: Add support for S3C6400 based SMDK6400 board Guennadi Liakhovetski
2008-08-04 20:10             ` Guennadi Liakhovetski
2008-07-31 19:55 ` [U-Boot-Users] [PATCH 6/7] NAND: add NAND driver for s3c64xx Jean-Christophe PLAGNIOL-VILLARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox