omap3_zoom1_config : unconfig
@$(MKCONFIG) $(@:_config=) arm arm_cortexa8 zoom1 omap3 omap3
+ omap3_zoom2_config : unconfig
+ @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 zoom2 omap3 omap3
+
+s5pc100_universal_config: unconfig
+ @echo "#define CONFIG_ONENAND_U_BOOT" > $(obj)include/config.h
+ @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 universal samsung s5pc100
+ @echo "CONFIG_ONENAND_U_BOOT = y" >> $(obj)include/config.mk
+
+s5pc100_smdkc100_config: unconfig
+ @echo "#define CONFIG_ONENAND_U_BOOT" > $(obj)include/config.h
+ @$(MKCONFIG) $(@:_config=) arm arm_cortexa8 smdkc100 samsung s5pc100
+ @echo "CONFIG_ONENAND_U_BOOT = y" >> $(obj)include/config.mk
+
#########################################################################
## XScale Systems
#########################################################################
@rm -f $(obj)cpu/mpc824x/bedbug_603e.c
@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f
- # @[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -name "*" -type l -print | xargs rm -f
+ @[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -name "*" -type l -print | xargs rm -f
+ @[ ! -d $(obj)api_examples ] || find $(obj)api_examples -name "*" -type l -print | xargs rm -f
ifeq ($(OBJTREE),$(SRCTREE))
mrproper \
--- /dev/null
- // this->base = (void *)CONFIG_SYS_ONENAND_BASE;
+/*
+ * OneNAND initialization at U-Boot
+ */
+
+#include <common.h>
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+#include <onenand_uboot.h>
+
+#include <s5pc1xx-onenand.h>
+
+#include <asm/io.h>
+
+#define DPRINTK(format, args...) \
+do { \
+ printk("%s[%d]: " format "\n", __func__, __LINE__, ##args); \
+} while (0)
+
+void onenand_board_init(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ int value;
+
+ /* D0 Domain system 1 clock gating */
+ value = S5P_CLK_GATE_D00_REG;
+ value &= ~(1 << 2); /* CFCON */
+ value |= (1 << 2);
+ S5P_CLK_GATE_D00_REG = value;
+
+ /* D0 Domain memory clock gating */
+ value = S5P_CLK_GATE_D01_REG;
+ value &= ~(1 << 2); /* CLK_ONENANDC */
+ value |= (1 << 2);
+ S5P_CLK_GATE_D01_REG = value;
+
+ /* System Special clock gating */
+ value = S5P_CLK_GATE_SCLK0_REG;
+ value &= ~(1 << 2); /* OneNAND */
+ value |= (1 << 2);
+ S5P_CLK_GATE_SCLK0_REG = value;
+
+ value = S5P_CLK_SRC0_REG;
+ value &= ~(1 << 24); /* MUX_1nand: 0 from HCLKD0 */
+// value |= (1 << 24); /* MUX_1nand: 1 from DIV_D1_BUS */
+ value &= ~(1 << 20); /* MUX_HREF: 0 from FIN_27M */
+ S5P_CLK_SRC0_REG = value;
+
+ value = S5P_CLK_DIV1_REG;
+// value &= ~(3 << 20); /* DIV_1nand: 1 / (ratio+1) */
+// value |= (0 << 20); /* ratio = 1 */
+ value &= ~(3 << 16);
+ value |= (1 << 16);
+ S5P_CLK_DIV1_REG = value;
+
+ MEM_RESET0_REG = ONENAND_MEM_RESET_COLD;
+
+ while (!(INT_ERR_STAT0_REG & RST_CMP))
+ continue;
+
+ INT_ERR_ACK0_REG = RST_CMP;
+
+ ACC_CLOCK0_REG = 0x3;
+
+ INT_ERR_MASK0_REG = 0x3fff;
+ INT_PIN_ENABLE0_REG = (1 << 0); /* Enable */
+
+ value = INT_ERR_MASK0_REG;
+ value &= ~RDY_ACT;
+ INT_ERR_MASK0_REG = value;
+
+#if 0
+ MEM_CFG0_REG |=
+ ONENAND_SYS_CFG1_SYNC_READ |
+ ONENAND_SYS_CFG1_BRL_4 |
+ ONENAND_SYS_CFG1_BL_16 |
+ ONENAND_SYS_CFG1_RDY |
+ ONENAND_SYS_CFG1_INT |
+ ONENAND_SYS_CFG1_IOBE
+ ;
+ MEM_CFG0_REG |= ONENAND_SYS_CFG1_RDY;
+ MEM_CFG0_REG |= ONENAND_SYS_CFG1_INT;
+ MEM_CFG0_REG |= ONENAND_SYS_CFG1_IOBE;
+#endif
+// MEM_CFG0_REG |= ONENAND_SYS_CFG1_VHF;
+// MEM_CFG0_REG |= ONENAND_SYS_CFG1_HF;
+
+ this->base = (void *) 0xe7100000;
- // s3c_onenand_init(mtd);
++ this->base = (void *)CONFIG_SYS_ONENAND_BASE;
+
++ s3c_onenand_init(mtd);
+}
COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o
COBJS-y += flash.o
COBJS-$(CONFIG_CMD_KGDB) += kgdb.o
+ COBJS-$(CONFIG_KALLSYMS) += kallsyms.o
COBJS-$(CONFIG_LCD) += lcd.o
COBJS-$(CONFIG_LYNXKDI) += lynxkdi.o
+ COBJS-$(CONFIG_MODEM_SUPPORT) += modem.o
COBJS-$(CONFIG_UPDATE_TFTP) += update.o
COBJS-$(CONFIG_USB_KEYBOARD) += usb_kbd.o
+COBJS-$(CONFIG_CMD_USBDOWN) += cmd_usbd.o
COBJS := $(sort $(COBJS-y))
# Supply options according to compiler version
#
# =========================================================================
--PLATFORM_CPPFLAGS +=$(call cc-option)
++PLATFORM_CPPFLAGS +=$(call cc-option,-mabi=aapcs-linux)
PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,)
PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\
-- $(call cc-option,-malignment-traps,))
++ $(call cc-option,-malignment-traps,))
--- /dev/null
- int interrupt_init(void)
+/*
+ * (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>
+ *
+ * (C) Copyright 2009
+ * Heungjun Kim, SAMSUNG Electronics, <riverful.kim@samsung.com>
+ * Inki Dae, SAMSUNG Electronics, <inki.dae@samsung.com>
+ * Minkyu Kang, SAMSUNG Electronics, <mk7.kang@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */
+#define MUX_DIV_2 (1) /* 1/2 period */
+#define MUX_DIV_4 (2) /* 1/4 period */
+#define MUX_DIV_8 (3) /* 1/8 period */
+#define MUX_DIV_16 (4) /* 1/16 period */
+#define MUX4_DIV_SHIFT 16
+
+#define TCON_TIMER4_SHIFT 20
+
+static ulong count_value;
+
+/* Internal tick units */
+static unsigned long long timestamp; /* Monotonic incrementing timer */
+static unsigned long lastdec; /* Last decremneter snapshot */
+
+/* macro to read the 16 bit timer */
+static inline ulong READ_TIMER(void)
+{
+ const s5pc1xx_timers_t *timers = (s5pc1xx_timers_t *) S5P_TIMER_BASE;
+
+ return timers->TCNTO4;
+}
+
-
++int timer_init(void)
+{
+ s5pc1xx_timers_t *timers = (s5pc1xx_timers_t *) S5P_TIMER_BASE;
+
+ /*
+ * @ PWM Timer 4
+ * Timer Freq(HZ) =
+ * PCLK / { (prescaler_value + 1) * (divider_value) }
+ */
+
+ /* set prescaler : 16 */
+ /* set divider : 2 */
+ timers->TCFG0 = (PRESCALER_1 & 0xff) << 8;
+ timers->TCFG1 = (MUX_DIV_2 & 0xf) << MUX4_DIV_SHIFT;
+
+ if (count_value == 0) {
+
+ /* reset initial value */
+ /* count_value = 2085937.5(HZ) (per 1 sec)*/
+ count_value = get_PCLK() / ((PRESCALER_1 + 1) *
+ (MUX_DIV_2 + 1));
+
+ /* count_value / 100 = 20859.375(HZ) (per 10 msec) */
+ count_value = count_value / 100;
+ }
+
+ /* set count value */
+ timers->TCNTB4 = count_value;
+ lastdec = count_value;
+
+ /* auto reload & manual update */
+ timers->TCON = (timers->TCON & ~(0x07 << TCON_TIMER4_SHIFT)) |
+ S5P_TCON4_AUTO_RELOAD | S5P_TCON4_UPDATE;
+
+ /* start PWM timer 4 */
+ timers->TCON = (timers->TCON & ~(0x07 << TCON_TIMER4_SHIFT)) |
+ S5P_TCON4_AUTO_RELOAD | S5P_TCON4_ON;
+
+ timestamp = 0;
+
+ return 0;
+}
+
+/*
+ * timer without interrupts
+ */
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+ulong get_timer(ulong base)
+{
+ return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+ timestamp = t;
+}
+
+/* delay x useconds */
+void udelay(unsigned long usec)
+{
+ ulong tmo, tmp;
+
+ if (usec >= 1000) {
+ /*
+ * if "big" number, spread normalization
+ * to seconds
+ * 1. start to normalize for usec to ticks per sec
+ * 2. find number of "ticks" to wait to achieve target
+ * 3. finish normalize.
+ */
+ tmo = usec / 1000;
+ tmo *= CONFIG_SYS_HZ;
+ tmo /= 1000;
+ } else {
+ /* else small number, don't kill it prior to HZ multiply */
+ tmo = usec * CONFIG_SYS_HZ;
+ tmo /= (1000 * 1000);
+ }
+
+ /* get current timestamp */
+ tmp = get_timer(0);
+
+ /* if setting this fordward will roll time stamp */
+ /* reset "advancing" timestamp to 0, set lastdec value */
+ /* else, set advancing stamp wake up time */
+ if ((tmo + tmp + 1) < tmp)
+ reset_timer_masked();
+ else
+ tmo += tmp;
+
+ /* loop till event */
+ while (get_timer_masked() < tmo)
+ ; /* nop */
+}
+
+void reset_timer_masked(void)
+{
+ /* reset time */
+ lastdec = READ_TIMER();
+ timestamp = 0;
+}
+
+ulong get_timer_masked(void)
+{
+ /* current tick value */
+ ulong now = READ_TIMER();
+
+ if (lastdec >= now)
+ timestamp += lastdec - now;
+ else
+ timestamp += lastdec + count_value - now;
+
+ lastdec = now;
+
+ return timestamp;
+}
+
+/*
+ * 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)
+{
+ return get_timer(0);
+}
+
+/*
+ * 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 CONFIG_SYS_HZ * 100;
+}
LIB := $(obj)libonenand.a
- #COBJS-$(CONFIG_CMD_ONENAND) := onenand_uboot.o onenand_base.o onenand_bbt.o
- #COBJS-$(CONFIG_S3C64XX) += s3c-onenand.o
- #COBJS-$(CONFIG_S5PC1XX) += s3c-onenand.o
- COBJS-$(CONFIG_S5PC1XX) += onenand_uboot.o lsi_onenand.o
+ COBJS-$(CONFIG_CMD_ONENAND) := onenand_uboot.o onenand_base.o onenand_bbt.o
++COBJS-$(CONFIG_S3C64XX) += s3c-onenand.o
++COBJS-$(CONFIG_S5PC1XX) += s3c-onenand.o
++#COBJS-$(CONFIG_S5PC1XX) += onenand_uboot.o lsi_onenand.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
--- /dev/null
-
- this->options |= ONENAND_RUNTIME_BADBLOCK_CHECK;
+/*
+ * S3C64XX/S5PC100 OneNAND driver at U-Boot
+ *
+ * Copyright (C) 2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Implementation:
+ * Emulate the pseudo BufferRAM
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <linux/mtd/compat.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/onenand.h>
+
+#if defined(CONFIG_S3C64XX)
+#include <s3c6400.h>
+#include <s3c64xx-onenand.h>
+#elif defined(CONFIG_S5PC1XX)
+#include <s5pc1xx-onenand.h>
+#endif
+
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#if 0
+#define DPRINTK(format, args...) \
+do { \
+ printk("%s[%d]: " format "\n", __func__, __LINE__, ##args); \
+} while (0)
+#else
+#define DPRINTK(...) do { } while (0)
+#endif
+
+#if defined(CONFIG_S3C64XX)
+#define AHB_ADDR 0x20000000
+#elif defined(CONFIG_S5PC1XX)
+#define AHB_ADDR 0xB0000000
+#endif
+
+#define ONENAND_ERASE_STATUS 0x00
+#define ONENAND_MULTI_ERASE_SET 0x01
+#define ONENAND_ERASE_START 0x03
+#define ONENAND_UNLOCK_START 0x08
+#define ONENAND_UNLOCK_END 0x09
+#define ONENAND_LOCK_START 0x0A
+#define ONENAND_LOCK_END 0x0B
+#define ONENAND_LOCK_TIGHT_START 0x0C
+#define ONENAND_LOCK_TIGHT_END 0x0D
+#define ONENAND_UNLOCK_ALL 0x0E
+#define ONENAND_OTP_ACCESS 0x12
+#define ONENAND_SPARE_ACCESS_ONLY 0x13
+#define ONENAND_MAIN_ACCESS_ONLY 0x14
+#define ONENAND_ERASE_VERIFY 0x15
+#define ONENAND_MAIN_SPARE_ACCESS 0x16
+#define ONENAND_PIPELINE_READ 0x4000
+
+#if defined(CONFIG_S3C64XX)
+#define MAP_00 (0x0 << 24)
+#define MAP_01 (0x1 << 24)
+#define MAP_10 (0x2 << 24)
+#define MAP_11 (0x3 << 24)
+#elif defined(CONFIG_S5PC1XX)
+#define MAP_00 (0x0 << 26)
+#define MAP_01 (0x1 << 26)
+#define MAP_10 (0x2 << 26)
+#define MAP_11 (0x3 << 26)
+#endif
+
+#if defined(CONFIG_S3C64XX)
+#define MEM_ADDR(fba, fpa, fsa) (((fba) << 12 | (fpa) << 6 | \
+ (fsa) << 4))
+#elif defined(CONFIG_S5PC1XX)
+#define MEM_ADDR(fba, fpa, fsa) (((fba) << 13 | (fpa) << 7 | \
+ (fsa) << 5))
+#endif
+
+/* The 'addr' is byte address. It makes a 16-bit word */
+#define CMD_MAP_00(addr) (MAP_00 | ((addr) << 1))
+#define CMD_MAP_01(mem_addr) (MAP_01 | (mem_addr))
+#define CMD_MAP_10(mem_addr) (MAP_10 | (mem_addr))
+#define CMD_MAP_11(addr) (MAP_11 | ((addr) << 2))
+
+struct s3c_onenand {
+ struct mtd_info *mtd;
+
+ void __iomem *base;
+ void __iomem *ahb_addr;
+
+ int bootram_command;
+
+ void __iomem *page_buf;
+ void __iomem *oob_buf;
+
+ unsigned int (*mem_addr)(int fba, int fpa, int fsa);
+};
+
+static struct s3c_onenand *onenand;
+
+static int s3c_read_reg(int offset)
+{
+ return readl(onenand->base + offset);
+}
+
+static void s3c_write_reg(int value, int offset)
+{
+ writel(value, onenand->base + offset);
+}
+
+static int s3c_read_cmd(unsigned int cmd)
+{
+ return readl(onenand->ahb_addr + cmd);
+}
+
+static void s3c_write_cmd(int value, unsigned int cmd)
+{
+ writel(value, onenand->ahb_addr + cmd);
+}
+
+static unsigned int s5pc100_mem_addr(int fba, int fpa, int fsa)
+{
+ return (fba << 13) | (fpa << 7) | (fsa << 5);
+}
+
+static void s3c_onenand_reset(void)
+{
+ unsigned long timeout = 0x10000;
+ int stat;
+
+ s3c_write_reg(ONENAND_MEM_RESET_COLD, MEM_RESET_OFFSET);
+ while (1 && timeout--) {
+ stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
+ if (stat & RST_CMP)
+ break;
+ }
+ stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
+ s3c_write_reg(stat, INT_ERR_ACK_OFFSET);
+
+ /* Clear interrupt */
+ s3c_write_reg(0x0, INT_ERR_ACK_OFFSET);
+ /* Clear the ECC status */
+ s3c_write_reg(0x0, ECC_ERR_STAT_OFFSET);
+}
+
+static unsigned short s3c_onenand_readw(void __iomem * addr)
+{
+ struct onenand_chip *this = onenand->mtd->priv;
+ int reg = addr - this->base;
+ int word_addr = reg >> 1;
+ int value;
+
+ /* It's used for probing time */
+ switch (reg) {
+ case ONENAND_REG_MANUFACTURER_ID:
+ return s3c_read_reg(MANUFACT_ID_OFFSET);
+ case ONENAND_REG_DEVICE_ID:
+ return s3c_read_reg(DEVICE_ID_OFFSET);
+ case ONENAND_REG_VERSION_ID:
+ return s3c_read_reg(FLASH_VER_ID_OFFSET);
+ case ONENAND_REG_DATA_BUFFER_SIZE:
+ return s3c_read_reg(DATA_BUF_SIZE_OFFSET);
+ case ONENAND_REG_TECHNOLOGY:
+ return s3c_read_reg(TECH_OFFSET);
+ case ONENAND_REG_SYS_CFG1:
+ return s3c_read_reg(MEM_CFG_OFFSET);
+
+ /* Used at unlock all status */
+ case ONENAND_REG_CTRL_STATUS:
+ return 0;
+
+ case ONENAND_REG_WP_STATUS:
+ return ONENAND_WP_US;
+
+ default:
+ break;
+ }
+
+ /* BootRAM access control */
+ if (reg < ONENAND_DATARAM && onenand->bootram_command) {
+ if (word_addr == 0)
+ return s3c_read_reg(MANUFACT_ID_OFFSET);
+ if (word_addr == 1)
+ return s3c_read_reg(DEVICE_ID_OFFSET);
+ if (word_addr == 2)
+ return s3c_read_reg(FLASH_VER_ID_OFFSET);
+ }
+
+ value = s3c_read_cmd(CMD_MAP_11(word_addr)) & 0xffff;
+ printk(KERN_INFO "s3c_onenand_readw: Illegal access"
+ " at reg 0x%x, value 0x%x\n", word_addr, value);
+ return value;
+}
+
+static void s3c_onenand_writew(unsigned short value, void __iomem * addr)
+{
+ struct onenand_chip *this = onenand->mtd->priv;
+ int reg = addr - this->base;
+ int word_addr = reg >> 1;
+
+ /* It's used for probing time */
+ switch (reg) {
+ case ONENAND_REG_SYS_CFG1:
+ s3c_write_reg(value, MEM_CFG_OFFSET);
+ return;
+
+ case ONENAND_REG_START_ADDRESS1:
+ case ONENAND_REG_START_ADDRESS2:
+ return;
+
+ /* Lock/lock-tight/unlock/unlock_all */
+ case ONENAND_REG_START_BLOCK_ADDRESS:
+ return;
+
+ default:
+ break;
+ }
+
+ /* BootRAM access control */
+ if (reg < ONENAND_DATARAM) {
+ if (value == ONENAND_CMD_READID) {
+ onenand->bootram_command = 1;
+ return;
+ }
+ if (value == ONENAND_CMD_RESET) {
+ s3c_write_reg(ONENAND_MEM_RESET_COLD, MEM_RESET_OFFSET);
+ onenand->bootram_command = 0;
+ return;
+ }
+ }
+
+ printk(KERN_INFO "s3c_onenand_writew: Illegal access"
+ " at reg 0x%x, value 0x%x\n", word_addr, value);
+
+ s3c_write_cmd(value, CMD_MAP_11(word_addr));
+}
+
+static int s3c_onenand_wait(struct mtd_info *mtd, int state)
+{
+ unsigned int flags = INT_ACT;
+ unsigned int stat, ecc;
+ unsigned long timeout = 0x100000;
+
+ switch (state) {
+ case FL_READING:
+ flags |= BLK_RW_CMP | LOAD_CMP;
+ break;
+ case FL_WRITING:
+ flags |= BLK_RW_CMP | PGM_CMP;
+ break;
+ case FL_ERASING:
+ flags |= BLK_RW_CMP | ERS_CMP;
+ break;
+ case FL_LOCKING:
+ flags |= BLK_RW_CMP;
+ break;
+ default:
+ break;
+ }
+
+ while (1 && timeout--) {
+ stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
+ if (stat & flags)
+ break;
+ for (stat = 0; stat < 2000; stat++)
+ continue;
+ }
+
+ /* To get correct interrupt status in timeout case */
+ stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
+ s3c_write_reg(stat, INT_ERR_ACK_OFFSET);
+
+ /*
+ *
+ * In the Spec. it checks the controller status first
+ * However if you get the correct information in case of
+ * power off recovery (POR) test, it should read ECC status first
+ */
+ if (stat & LOAD_CMP) {
+ ecc = s3c_read_reg(ECC_ERR_STAT_OFFSET);
+ if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
+ printk(KERN_INFO "onenand_wait: ECC error = 0x%04x\n", ecc);
+ mtd->ecc_stats.failed++;
+ return -EBADMSG;
+ }
+#if 0
+ } else if (ecc & ONENAND_ECC_1BIT_ALL) {
+ printk(KERN_INFO "onenand_wait: correctable ECC error = 0x%04x\n", ecc);
+ mtd->ecc_stats.corrected++;
+ }
+#endif
+ }
+
+ if (stat & (LOCKED_BLK | ERS_FAIL | PGM_FAIL | LD_FAIL_ECC_ERR)) {
+ printk(KERN_INFO "s3c_onenand_wait: controller error = 0x%04x\n", stat);
+ if (stat & LOCKED_BLK)
+ printk(KERN_INFO "s3c_onenand_wait: it's locked error = 0x%04x\n", stat);
+
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int s3c_onenand_command(struct mtd_info *mtd, int cmd, loff_t addr,
+ size_t len)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned int *m, *s;
+ int fba, fpa, fsa = 0;
+ unsigned int mem_addr;
+ int i, mcount, scount;
+ int index;
+
+ fba = (int) (addr >> this->erase_shift);
+ fpa = (int) (addr >> this->page_shift);
+ fpa &= this->page_mask;
+
+ mem_addr = onenand->mem_addr(fba, fpa, fsa);
+
+ switch (cmd) {
+ case ONENAND_CMD_READ:
+ case ONENAND_CMD_READOOB:
+ case ONENAND_CMD_BUFFERRAM:
+ ONENAND_SET_NEXT_BUFFERRAM(this);
+ default:
+ break;
+ }
+
+ index = ONENAND_CURRENT_BUFFERRAM(this);
+
+ /*
+ * Emulate Two BufferRAMs and access with 4 bytes pointer
+ */
+ m = (unsigned int *) onenand->page_buf;
+ s = (unsigned int *) onenand->oob_buf;
+
+ if (index) {
+ m += (this->writesize >> 2);
+ s += (mtd->oobsize >> 2);
+ }
+
+ mcount = mtd->writesize >> 2;
+ scount = mtd->oobsize >> 2;
+
+ switch (cmd) {
+ case ONENAND_CMD_READ:
+ /* Main */
+ for (i = 0; i < mcount; i++)
+ *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_READOOB:
+ s3c_write_reg(TSRF, TRANS_SPARE_OFFSET);
+ /* Main */
+ for (i = 0; i < mcount; i++)
+ *m++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
+
+ /* Spare */
+ for (i = 0; i < scount; i++)
+ *s++ = s3c_read_cmd(CMD_MAP_01(mem_addr));
+
+ s3c_write_reg(0, TRANS_SPARE_OFFSET);
+ return 0;
+
+ case ONENAND_CMD_PROG:
+ /* Main */
+ for (i = 0; i < mcount; i++)
+ s3c_write_cmd(*m++, CMD_MAP_01(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_PROGOOB:
+ s3c_write_reg(TSRF, TRANS_SPARE_OFFSET);
+
+ /* Main - dummy write */
+ for (i = 0; i < mcount; i++)
+ s3c_write_cmd(0xffffffff, CMD_MAP_01(mem_addr));
+
+ /* Spare */
+ for (i = 0; i < scount; i++)
+ s3c_write_cmd(*s++, CMD_MAP_01(mem_addr));
+
+ s3c_write_reg(0, TRANS_SPARE_OFFSET);
+ return 0;
+
+ case ONENAND_CMD_UNLOCK_ALL:
+ s3c_write_cmd(ONENAND_UNLOCK_ALL, CMD_MAP_10(mem_addr));
+ return 0;
+
+ case ONENAND_CMD_ERASE:
+ s3c_write_cmd(ONENAND_ERASE_START, CMD_MAP_10(mem_addr));
+ return 0;
+
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static unsigned char *s3c_get_bufferram(struct mtd_info *mtd, int area)
+{
+ struct onenand_chip *this = mtd->priv;
+ int index = ONENAND_CURRENT_BUFFERRAM(this);
+ unsigned char *p;
+
+ if (area == ONENAND_DATARAM) {
+ p = (unsigned char *) onenand->page_buf;
+ if (index == 1)
+ p += this->writesize;
+ } else {
+ p = (unsigned char *) onenand->oob_buf;
+ if (index == 1)
+ p += mtd->oobsize;
+ }
+
+ return p;
+}
+
+static int onenand_read_bufferram(struct mtd_info *mtd, loff_t addr, int area,
+ unsigned char *buffer, int offset,
+ size_t count)
+{
+ unsigned char *p;
+
+ p = s3c_get_bufferram(mtd, area);
+ memcpy(buffer, p + offset, count);
+ return 0;
+}
+
+static int onenand_write_bufferram(struct mtd_info *mtd, loff_t addr, int area,
+ const unsigned char *buffer, int offset,
+ size_t count)
+{
+ unsigned char *p;
+
+ p = s3c_get_bufferram(mtd, area);
+ memcpy(p + offset, buffer, count);
+ return 0;
+}
+
+static int s3c_onenand_bbt_wait(struct mtd_info *mtd, int state)
+{
+ unsigned int flags = INT_ACT | LOAD_CMP;
+ unsigned int stat;
+ unsigned long timeout = 0x10000;
+
+ while (1 && timeout--) {
+ stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
+ if (stat & flags)
+ break;
+ }
+ /* To get correct interrupt status in timeout case */
+ stat = s3c_read_reg(INT_ERR_STAT_OFFSET);
+ s3c_write_reg(stat, INT_ERR_ACK_OFFSET);
+
+ if (stat & LD_FAIL_ECC_ERR) {
+ s3c_onenand_reset();
+ return ONENAND_BBT_READ_ERROR;
+ }
+
+ if (stat & LOAD_CMP) {
+ int ecc = s3c_read_reg(ECC_ERR_STAT_OFFSET);
+ if (ecc & ONENAND_ECC_4BIT_UNCORRECTABLE) {
+ s3c_onenand_reset();
+ return ONENAND_BBT_READ_ERROR;
+ }
+ }
+
+ return 0;
+}
+
+static void s3c_onenand_check_lock_status(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ unsigned int block, end;
+ int tmp;
+
+ end = this->chipsize >> this->erase_shift;
+
+ for (block = 0; block < end; block++) {
+ tmp = s3c_read_cmd(CMD_MAP_01(onenand->mem_addr(block, 0, 0)));
+
+ if (s3c_read_reg(INT_ERR_STAT_OFFSET) & LOCKED_BLK) {
+ printf("block %d is write-protected!\n", block);
+ s3c_write_reg(LOCKED_BLK, INT_ERR_ACK_OFFSET);
+ }
+ }
+}
+
+static void s3c_onenand_do_lock_cmd(struct mtd_info *mtd, loff_t ofs, size_t len, int cmd)
+{
+ struct onenand_chip *this = mtd->priv;
+ int start, end, start_mem_addr, end_mem_addr;
+
+ start = ofs >> this->erase_shift;
+ start_mem_addr = onenand->mem_addr(start, 0, 0);
+ end = start + (len >> this->erase_shift) - 1;
+ end_mem_addr = onenand->mem_addr(end, 0, 0);
+
+ if (cmd == ONENAND_CMD_LOCK) {
+ s3c_write_cmd(ONENAND_LOCK_START, CMD_MAP_10(start_mem_addr));
+ s3c_write_cmd(ONENAND_LOCK_END, CMD_MAP_10(end_mem_addr));
+ } else {
+ s3c_write_cmd(ONENAND_UNLOCK_START, CMD_MAP_10(start_mem_addr));
+ s3c_write_cmd(ONENAND_UNLOCK_END, CMD_MAP_10(end_mem_addr));
+ }
+
+ this->wait(mtd, FL_LOCKING);
+}
+
+static void s3c_onenand_unlock_all(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+ loff_t ofs = 0;
+ size_t len = this->chipsize;
+
+ if (this->options & ONENAND_HAS_UNLOCK_ALL) {
+ /* Write unlock command */
+ this->command(mtd, ONENAND_CMD_UNLOCK_ALL, 0, 0);
+
+ /* No need to check return value */
+ this->wait(mtd, FL_LOCKING);
+
+ /* Workaround for all block unlock in DDP */
+ if (!ONENAND_IS_DDP(this)) {
+ s3c_onenand_check_lock_status(mtd);
+ return;
+ }
+
+ /* All blocks on another chip */
+ ofs = this->chipsize >> 1;
+ len = this->chipsize >> 1;
+ }
+
+ s3c_onenand_do_lock_cmd(mtd, ofs, len, ONENAND_CMD_UNLOCK);
+
+// s3c_onenand_check_lock_status(mtd);
+}
+
+#ifdef CONFIG_S3C64XX
+static void s3c_set_width_regs(struct onenand_chip *this)
+{
+ int dev_id, density;
+ int fba, fpa, fsa;
+ int dbs_dfs;
+
+ dev_id = DEVICE_ID0_REG;
+
+ density = (dev_id >> ONENAND_DEVICE_DENSITY_SHIFT) & 0xf;
+ dbs_dfs = !!(dev_id & ONENAND_DEVICE_IS_DDP);
+
+ fba = density + 7;
+ if (dbs_dfs)
+ fba--; /* Decrease the fba */
+ fpa = 6;
+ if (density >= ONENAND_DEVICE_DENSITY_512Mb)
+ fsa = 2;
+ else
+ fsa = 1;
+
+ DPRINTK("FBA %lu, FPA %lu, FSA %lu, DDP %lu",
+ FBA_WIDTH0_REG, FPA_WIDTH0_REG, FSA_WIDTH0_REG,
+ DDP_DEVICE_REG);
+
+ DPRINTK("mem_cfg0 0x%lx, sync mode %lu, dev_page_size %lu, BURST LEN %lu",
+ MEM_CFG0_REG,
+ SYNC_MODE_REG,
+ DEV_PAGE_SIZE_REG,
+ BURST_LEN0_REG
+ );
+
+ DEV_PAGE_SIZE_REG = 0x1;
+
+ FBA_WIDTH0_REG = fba;
+ FPA_WIDTH0_REG = fpa;
+ FSA_WIDTH0_REG = fsa;
+ DBS_DFS_WIDTH0_REG = dbs_dfs;
+}
+#endif
+
+void s3c_onenand_init(struct mtd_info *mtd)
+{
+ struct onenand_chip *this = mtd->priv;
+
+ onenand = malloc(sizeof(struct s3c_onenand));
+ if (!onenand)
+ return;
+
+ onenand->page_buf = malloc(SZ_4K * sizeof(char));
+ if (!onenand->page_buf)
+ return;
+ memset(onenand->page_buf, 0xFF, SZ_4K);
+
+ onenand->oob_buf = malloc(128 * sizeof(char));
+ if (!onenand->oob_buf)
+ return;
+ memset(onenand->oob_buf, 0xFF, 128);
+
+ onenand->mtd = mtd;
+
+ /* S5PC100 specific values */
+ onenand->base = (void *) 0xE7100000;
+ onenand->ahb_addr = (void *) 0xB0000000;
+ onenand->mem_addr = s5pc100_mem_addr;
+
+ this->read_word = s3c_onenand_readw;
+ this->write_word = s3c_onenand_writew;
+
+ this->wait = s3c_onenand_wait;
+ this->bbt_wait = s3c_onenand_bbt_wait;
+ this->unlock_all = s3c_onenand_unlock_all;
+ this->command = s3c_onenand_command;
+
+ this->read_bufferram = onenand_read_bufferram;
+ this->write_bufferram = onenand_write_bufferram;
+}
--- /dev/null
+/*
+ * Copyright (C) 2009 Samsung Electronics
+ * Minkyu Kang <mk7.kang@samsung.com>
+ *
+ * Configuation settings for the SAMSUNG Universal (s5pc100) 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
+#include <asm/sizes.h>
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARMCORTEXA8 1 /* This is an ARM V7 CPU core */
+#define CONFIG_SAMSUNG 1 /* in a SAMSUNG core */
+#define CONFIG_S5PC1XX 1 /* which is in a S5PC1XX Family */
+#define CONFIG_S5PC100 1 /* which is in a S5PC100 */
+#define CONFIG_UNIVERSAL 1 /* working with Universal */
+
+#include <asm/arch/cpu.h> /* get chip and board defs */
+
+#define CONFIG_SYS_SDRAM_BASE 0x20000000
+
+/* input clock of PLL: Universal 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
+#define CONFIG_REVISION_TAG
+
+/* Clock Defines */
+#define V_OSCK 26000000 /* Clock output from T2 */
+#define V_SCLK (V_OSCK >> 1)
+
+/*
+ * Architecture magic and machine type
+ */
+#define MACH_TYPE 3000
+
+#define CONFIG_DISPLAY_CPUINFO
+
+#undef CONFIG_SKIP_RELOCATE_UBOOT
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 1024 * 1024)
+#define CONFIG_SYS_GBL_DATA_SIZE 128 /* size in bytes for initial data */
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_SERIAL2 1 /* we use SERIAL 2 on S5PC100 */
+
+#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */
+#ifdef CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
+#endif
+
+#define CONFIG_CMDLINE_EDITING
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE 115200
+#define CONFIG_L2_OFF
+
+/***********************************************************
+ * Command definition
+ ***********************************************************/
+#include <config_cmd_default.h>
+
+#undef CONFIG_CMD_LOADB
+#undef CONFIG_CMD_LOADS
+#undef CONFIG_CMD_BOOTD
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_XIMG
+#undef CONFIG_CMD_NAND
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_FLASH
+#undef CONFIG_CMD_IMLS
+#undef CONFIG_CMD_NET
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_REGINFO
+#define CONFIG_CMD_ONENAND
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_MTDPARTS
+
+#define CONFIG_BOOTDELAY 1
+
+#define CONFIG_ZERO_BOOTDELAY_CHECK
+
++#define CONFIG_MTD_DEVICE
+#define CONFIG_MTD_PARTITIONS
+
+#define MTDIDS_DEFAULT "onenand0=s3c-onenand"
+#define MTDPARTS_DEFAULT "mtdparts=s3c-onenand:256k(bootloader)"\
+ ",128k@0x40000(params)"\
+ ",3m@0x60000(kernel)"\
+ ",16m@0x260000(test)"\
+ ",-(UBI)"
+
+#define NORMAL_MTDPARTS_DEFAULT MTDPARTS_DEFAULT
+
+#if 1
+#define CONFIG_BOOTCOMMAND "run ubifsboot"
+#else
+#define CONFIG_BOOTCOMMAND "bootm 0x21008000"
+#endif
+
+#define CONFIG_RAMDISK_BOOT "root=/dev/ram0 rw rootfstype=ext2" \
+ " console=ttySAC2,115200n8" \
+ " ${meminfo}"
+
+#define CONFIG_COMMON_BOOT "console=ttySAC2,115200n8" \
+ " ${meminfo} " \
+ " " MTDPARTS_DEFAULT
+
+#define CONFIG_BOOTARGS "root=/dev/mtdblock5 ubi.mtd=4" \
+ " rootfstype=cramfs " CONFIG_COMMON_BOOT
+
++#define CONFIG_USE_BIG_UBOOT 1
+#ifdef CONFIG_USE_BIG_UBOOT
+#define CONFIG_UPDATEB "updateb=onenand erase 0x0 0x40000;" \
+ " onenand write 0x22008000 0x0 0x40000\0"
+#else
+#define CONFIG_UPDATEB "updateb=onenand erase 0x0 0x40000;" \
+ " onenand write 0x22008000 0x0 0x20000;" \
+ " onenand write 0x22008000 0x20000 0x20000\0"
+#endif
+
+#define CONFIG_ENV_OVERWRITE
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ CONFIG_UPDATEB \
+ "updatek=onenand erase 0x60000 0x200000;" \
+ " onenand write 0x21008000 0x60000 0x200000\0" \
+ "updateu=onenand erase block 147-4095;" \
+ " onenand write 0x22000000 0x1260000 0x8C0000\0" \
+ "bootk=onenand read 0x20007FC0 0x60000 0x300000;" \
+ " bootm 0x20007FC0\0" \
+ "flashboot=set bootargs root=/dev/mtdblock${bootblock}" \
+ " rootfstype=${rootfstype}" \
+ " ubi.mtd=${ubiblock} ${opts} " CONFIG_COMMON_BOOT "; run bootk\0" \
+ "ubifsboot=set bootargs root=ubi0!rootfs rootfstype=ubifs" \
+ " ubi.mtd=${ubiblock} ${opts} " CONFIG_COMMON_BOOT "; run bootk\0" \
+ "boottrace=setenv opts initcall_debug; run bootcmd\0" \
+ "android=set bootargs root=ubi0!ramdisk ubi.mtd=${ubiblock}" \
+ " rootfstype=ubifs init=/init.sh " CONFIG_COMMON_BOOT "; run bootk\0" \
+ "nfsboot=set bootargs root=/dev/nfs ubi.mtd=${ubiblock}" \
+ " nfsroot=${nfsroot},nolock ip=${ipaddr}:${serverip}:${gatewayip}:" \
+ " ${netmask}:nowplus:usb0:off " CONFIG_COMMON_BOOT "; run bootk\0" \
+ "ramboot=set bootargs " CONFIG_RAMDISK_BOOT \
+ " initrd=0x23000000,8M ramdisk=8192\0" \
+ "rootfstype=cramfs\0" \
+ "mtdparts=" MTDPARTS_DEFAULT "\0" \
+ "meminfo=mem=208M\0" \
+ "nfsroot=/nfsroot/arm\0" \
+ "bootblock=5\0" \
+ "ubiblock=4\0" \
+ "ubi=enabled"
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP /* undef to save memory */
+#define CONFIG_SYS_PROMPT "Universal # " /* Monitor Command Prompt */
+#define CONFIG_SYS_CBSIZE 256 /* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE 384 /* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS 16 /* max number of command args */
+#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE /* Boot Argument Buffer Size */
+
+#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE /* memtest works on */
+#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 0x4e00000)
+
+#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x4e00000)
+
+#define CONFIG_SYS_TIMERBASE (OMAP34XX_GPT2)
+#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
+#define CONFIG_SYS_HZ 2085900 /* at PCLK 66.75MHz */
+
+/* valid baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE 0x40000 /* regular stack 256KB */
+
+/*******************************
+ Support Clock Settings(APLL)
+ *******************************
+ ARMCLK HCLKD0 PCLKD0
+ -------------------------------
+ 667 166 83
+ 600 150 75
+ 533 133 66
+ 500 166 66
+ 467 117 59
+ 400 100 50
+ *******************************/
+
+#define CONFIG_CLK_667_166_83
+/*#define CONFIG_CLK_600_150_75*/
+/*#define CONFIG_CLK_533_133_66*/
+/*#define CONFIG_CLK_500_166_66*/
+/*#define CONFIG_CLK_467_117_59*/
+/*#define CONFIG_CLK_400_100_50*/
+
+/* Universal has 2 banks of DRAM, but swap the bank */
+#define CONFIG_NR_DRAM_BANKS 2
+#define CONFIG_S5PC1XX_SWAP_MEMORY_BANK 1
+#define PHYS_SDRAM_1 CONFIG_SYS_SDRAM_BASE /* OneDRAM Bank #0 */
+#define PHYS_SDRAM_1_SIZE 0x05000000 /* 80 MB in Bank #0 */
+#define PHYS_SDRAM_2 0x28000000 /* MobileDDR Bank #1 */
+#define PHYS_SDRAM_2_SIZE 0x08000000 /* 128 MB in Bank #1 */
+
+#define CONFIG_SYS_MONITOR_BASE 0x00000000
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH 1
+
+#define CONFIG_SYS_MONITOR_LEN SZ_256K /* Reserve 2 sectors */
+
+#ifdef CONFIG_ENABLE_MMU
+#define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000
+#else
+#define CONFIG_SYS_MAPPED_RAM_BASE CONFIG_SYS_SDRAM_BASE
+#endif
+
+/* Boot configuration (define only one of next 3) */
+//#define CONFIG_BOOT_ONENAND
+
+#define CONFIG_ENV_IS_IN_ONENAND 1
+#define CONFIG_ENV_SIZE 0x20000
+#define CONFIG_ENV_ADDR 0x40000
+#define CONFIG_ENV_OFFSET 0x40000
+
+#define CONFIG_USE_ONENAND_BOARD_INIT
+#define CONFIG_SYS_ONENAND_BASE 0x00000000
+
+#define CONFIG_DOS_PARTITION 1
+
+#define CONFIG_MISC_INIT_R
+
+/* I2C */
+#define CONFIG_DRIVER_S5PC1XX_I2C
+#define CONFIG_HARD_I2C 1
+#define CONFIG_SYS_I2C_SPEED 50000
+#define CONFIG_SYS_I2C_SLAVE 0xFE
+#define CONFIG_SYS_I2C_0 1
+
+/* USB Downloader */
+#define CONFIG_CMD_USBDOWN
+#define CONFIG_SAMSUNG_USB
+#define CONFIG_OTG_CLK_OSCC
+#define CONFIG_SYS_DOWN_ADDR CONFIG_SYS_SDRAM_BASE
+#define CONFIG_RAMDISK_ADDR 0x23000000
+
+#endif /* __CONFIG_H */