现在的位置: 首页 > 综合 > 正文

uboot-2010.06移植到TQ2440开发板补丁文件

2013年02月20日 ⁄ 综合 ⁄ 共 49129字 ⁄ 字号 评论关闭

   将本文件中的内容对uboot-2010.06源码打补丁,之后再编译,生成uboot.bin就可以直接在TQ2440开发板运行了(使用天嵌光盘自带的内核源码配置单,做出uImage)。

diff -urNwB u-boot-2010.06/arch/arm/cpu/arm920t/s3c24x0/Makefile uboot-2010.06/arch/arm/cpu/arm920t/s3c24x0/Makefile
--- u-boot-2010.06/arch/arm/cpu/arm920t/s3c24x0/Makefile 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/cpu/arm920t/s3c24x0/Makefile 2012-05-09 21:14:35.433310758 +0800
@@ -30,6 +30,7 @@
COBJS-y += timer.o
COBJS-y += usb.o
COBJS-y += usb_ohci.o
+COBJS-y += nand_flash.o

SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
diff -urNwB u-boot-2010.06/arch/arm/cpu/arm920t/s3c24x0/nand_flash.c uboot-2010.06/arch/arm/cpu/arm920t/s3c24x0/nand_flash.c
--- u-boot-2010.06/arch/arm/cpu/arm920t/s3c24x0/nand_flash.c 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/arch/arm/cpu/arm920t/s3c24x0/nand_flash.c 2012-05-09 21:14:35.435093757 +0800
@@ -0,0 +1,164 @@
+#include <common.h>
+#include <nand.h>
+#include <asm/arch/s3c24x0_cpu.h>
+#include <asm/io.h>
+
+#define S3C2440_NFCONT_nCE (1<<1)
+#define S3C2440_ADDR_NALE 0x0C
+#define S3C2440_ADDR_NCLE 0x08
+
+#ifdef CONFIG_NAND_SPL
+
+/* in the early stage of NAND flash booting, printf() is not available */
+#define printf(fmt, args...)
+
+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 s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
+{
+ struct nand_chip *chip = mtd->priv;
+ struct s3c2440_nand *nand = s3c2440_get_base_nand();
+
+ debugX(1, "hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
+
+ if (ctrl & NAND_CTRL_CHANGE) {
+ ulong IO_ADDR_W = (ulong)nand;
+/*
+ if (!(ctrl & NAND_CLE))
+ IO_ADDR_W |= S3C2440_ADDR_NALE;
+ if (!(ctrl & NAND_ALE))
+ IO_ADDR_W |= S3C2440_ADDR_NCLE;
+*/
+ if ((ctrl & NAND_CLE))
+ IO_ADDR_W |= S3C2440_ADDR_NCLE;
+ else if ((ctrl & NAND_ALE))
+ IO_ADDR_W |= S3C2440_ADDR_NALE;
+ else
+ IO_ADDR_W |= 0x10;
+
+ chip->IO_ADDR_W = (void *)IO_ADDR_W;
+
+ if (ctrl & NAND_NCE)
+ writel(readl(&nand->NFCONT) & ~S3C2440_NFCONT_nCE,
+ &nand->NFCONT);
+ else
+ writel(readl(&nand->NFCONT) | S3C2440_NFCONT_nCE,
+ &nand->NFCONT);
+ }
+ //printf("In s3c2440_hwcontrol.ctrl is 0x%x,cmd is 0x%x\n",ctrl,cmd);
+ if (cmd != NAND_CMD_NONE)
+ writeb(cmd, chip->IO_ADDR_W);
+}
+
+static int s3c2440_dev_ready(struct mtd_info *mtd)
+{
+ struct s3c2440_nand *nand = s3c2440_get_base_nand();
+ unsigned int ready=0;
+ ready = readl(&nand->NFSTAT) & 0x01;
+ //printf("In s3c2440_dev_ready,dev is %s ready.\n",ready? "":"not");
+ return ready;
+}
+/*
+#ifdef CONFIG_S3C2410_NAND_HWECC
+void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)
+{
+ struct s3c2410_nand *nand = s3c2410_get_base_nand();
+ debugX(1, "s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);
+ writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);
+}
+
+static int s3c2410_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
+ u_char *ecc_code)
+{
+ struct s3c2410_nand *nand = s3c2410_get_base_nand();
+ ecc_code[0] = readb(&nand->NFECC);
+ ecc_code[1] = readb(&nand->NFECC + 1);
+ ecc_code[2] = readb(&nand->NFECC + 2);
+ debugX(1, "s3c2410_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
+ mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
+
+ return 0;
+}
+
+static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
+ u_char *read_ecc, u_char *calc_ecc)
+{
+ if (read_ecc[0] == calc_ecc[0] &&
+ read_ecc[1] == calc_ecc[1] &&
+ read_ecc[2] == calc_ecc[2])
+ return 0;
+
+ printf("s3c2410_nand_correct_data: not implemented\n");
+ return -1;
+}
+#endif
+*/
+int board_nand_init(struct nand_chip *nand)
+{
+ u_int32_t cfg;
+ u_int8_t tacls, twrph0, twrph1;
+ struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
+ struct s3c2440_nand *nand_reg = s3c2440_get_base_nand();
+
+ debugX(1, "board_nand_init()\n");
+ //printf("In board_nand_init.\n");
+
+ writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON);
+
+ /* initialize hardware */
+ twrph0 = 4;
+ twrph1 = 2;
+ tacls = 0;
+
+ cfg = (tacls<<12) | (twrph0<<8) | (twrph1<<4);
+ writel(cfg, &nand_reg->NFCONF);
+ cfg = (1<<4) | (0<<1) | (1<<0);
+ writel(cfg, &nand_reg->NFCONT);
+
+ /* initialize nand_chip data structure */
+ nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;
+
+ nand->select_chip = NULL;
+
+ /* read_buf and write_buf are default */
+ /* read_byte and write_byte are default */
+#ifdef CONFIG_NAND_SPL
+ nand->read_buf = nand_read_buf;
+#endif
+
+ /* hwcontrol always must be implemented */
+ nand->cmd_ctrl = s3c2440_hwcontrol;
+
+ nand->dev_ready = s3c2440_dev_ready;
+/*
+#ifdef CONFIG_S3C2410_NAND_HWECC
+ nand->ecc.hwctl = s3c2410_nand_enable_hwecc;
+ nand->ecc.calculate = s3c2410_nand_calculate_ecc;
+ nand->ecc.correct = s3c2410_nand_correct_data;
+ nand->ecc.mode = NAND_ECC_HW;
+ nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
+ nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+#else
+ nand->ecc.mode = NAND_ECC_SOFT;
+#endif
+
+#ifdef CONFIG_S3C2410_NAND_BBT
+ nand->options = NAND_USE_FLASH_BBT;
+#else
+ nand->options = 0;
+#endif
+*/
+ nand->options = 0; //位宽为8
+ nand->ecc.mode = NAND_ECC_SOFT; //软件ECC校验
+ debugX(1, "end of nand_init\n");
+
+ return 0;
+}
diff -urNwB u-boot-2010.06/arch/arm/cpu/arm920t/s3c24x0/speed.c uboot-2010.06/arch/arm/cpu/arm920t/s3c24x0/speed.c
--- u-boot-2010.06/arch/arm/cpu/arm920t/s3c24x0/speed.c 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/cpu/arm920t/s3c24x0/speed.c 2012-05-09 21:14:35.435093757 +0800
@@ -64,7 +64,8 @@
p = ((r & 0x003F0) >> 4) + 2;
s = r & 0x3;

- return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
+ //return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
+ return (CONFIG_SYS_CLK_FREQ * m * 2) / (p << s);
}

/* return FCLK frequency */
@@ -77,16 +78,38 @@
ulong get_HCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
-
- return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();
+ ulong r,hdivn,hclkn,hdiv;
+ r = readl(&clk_power->CLKDIVN);
+ hdivn = r & 0x6;
+ r = readl(&clk_power->CAMDIVN);
+ switch(hdivn)
+ { //hdiv、hclkn为从硬件寄存器中读出的时钟分频因子,参考芯片手册
+ case 0x0: hdiv = 1;break;
+ case 0x2: hdiv = 2;break;
+ case 0x4:
+ hclkn = (r & 0x200) >> 9;
+ hdiv = (hclkn == 1)? 8:4;
+ break;
+ case 0x6:
+ hclkn = (r & 0x100) >> 8;
+ hdiv = (hclkn == 1)? 6:3;
+ break;
+ }
+ return get_FCLK() / hdiv;
+ //return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();
}

/* return PCLK frequency */
ulong get_PCLK(void)
{
struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
+ ulong r,pdivn,pdiv;

- return (readl(&clk_power->CLKDIVN) & 1) ? get_HCLK() / 2 : get_HCLK();
+ r = readl(&clk_power->CLKDIVN);
+ pdivn = r & 0x1;
+ pdiv = (pdivn == 1)? 2:1;
+ return get_HCLK()/pdiv;
+ //return (readl(&clk_power->CLKDIVN) & 1) ? get_HCLK() / 2 : get_HCLK();
}

/* return UCLK frequency */
@@ -95,4 +118,10 @@
return get_PLLCLK(UPLL);
}

+int print_cpuinfo(void)
+{
+ printf("TQ2440 CLK: Fclk = %luMHz, Hclk = %luMHz, Pclk = %luMHz\n",
+ get_FCLK() / 1000000, get_HCLK() / 1000000,get_PCLK() / 1000000);
+}
+
#endif /* CONFIG_S3C24X0 */
diff -urNwB u-boot-2010.06/arch/arm/cpu/arm920t/start.S uboot-2010.06/arch/arm/cpu/arm920t/start.S
--- u-boot-2010.06/arch/arm/cpu/arm920t/start.S 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/cpu/arm920t/start.S 2012-05-09 21:14:35.435093757 +0800
@@ -114,8 +114,8 @@
orr r0, r0, #0xd3
msr cpsr, r0

- bl coloured_LED_init
- bl red_LED_on
+ //bl coloured_LED_init
+ //bl red_LED_on

#if defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
/*
@@ -160,12 +160,40 @@
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
-
+#if 0
/* FCLK:HCLK:PCLK = 1:2:4 */
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
+#endif
+
+#define MPLLCON 0x4C000004 /**/
+#define UPLLCON 0x4C000008
+ mrc p15, 0, r1, c1, c0, 0 /*Asynchronous.read ctrl register*/
+ orr r1, r1, #0xc0000000 /*Asynchronous*/
+ mcr p15, 0, r1, c1, c0, 0 /*write ctrl register*/
+ ldr r0,=CLKDIVN /**/
+ mov r1,#5
+ str r1,[r0]
+ nop
+ nop
+ nop
+ nop
+ nop
+ ldr r0,=UPLLCON /*USB*/
+ ldr r1,=0x38022
+ str r1,[r0]
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ ldr r0,=MPLLCON /*405MHZ*/
+ ldr r1,=0x7f021
+ str r1,[r0]
#endif /* CONFIG_S3C24X0 */

/*
@@ -175,17 +203,49 @@
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
+/********************************************************************/
+#if defined(CONFIG_S3C2440)
+#define GPBCON 0x56000010
+#define GPBDAT 0x56000014
+#define GPBUP 0x56000018
+ ldr r0,=GPBUP
+ ldr r1,=0x7ff
+ str r1,[r0]
+
+ ldr r0,=GPBCON
+ ldr r1,=0x154FD
+ str r1,[r0]
+
+ ldr r0,=GPBDAT
+ ldr r1,=0x1C0
+ str r1,[r0]
+#endif
+/********************************************************************/
+
+stack_setup:
+ ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
+ sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
+#ifdef CONFIG_USE_IRQ
+ sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+ sub sp, r0, #12 /* leave 3 words for abort-stack */
+ bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
- beq stack_setup
+ /*beq stack_setup */
+ beq clear_bss

ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
+#if 1
+ bl CopyCode2Ram
+#else
add r2, r0, r2 /* r2 <- source end address */

copy_loop:
@@ -193,18 +253,10 @@
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
+#endif
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

/* Set up the stack */
-stack_setup:
- ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
- sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
- sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
-#ifdef CONFIG_USE_IRQ
- sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
-#endif
- sub sp, r0, #12 /* leave 3 words for abort-stack */
- bic sp, sp, #7 /* 8-byte alignment for ABI compliance */

clear_bss:
ldr r0, _bss_start /* find start of bss segment */
@@ -257,8 +309,8 @@
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
- mov ip, lr

+ mov ip, lr
bl lowlevel_init

mov lr, ip
diff -urNwB u-boot-2010.06/arch/arm/cpu/arm920t/u-boot.lds uboot-2010.06/arch/arm/cpu/arm920t/u-boot.lds
--- u-boot-2010.06/arch/arm/cpu/arm920t/u-boot.lds 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/cpu/arm920t/u-boot.lds 2012-05-09 21:14:35.436230178 +0800
@@ -40,6 +40,7 @@
.text :
{
arch/arm/cpu/arm920t/start.o (.text)
+ board/samsung/tq2440/nand_start.o (.text)
*(.text)
}

diff -urNwB u-boot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c2410.h uboot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c2410.h
--- u-boot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c2410.h 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c2410.h 2012-05-09 21:14:35.436230178 +0800
@@ -52,6 +52,7 @@
#define S3C24X0_CLOCK_POWER_BASE 0x4C000000
#define S3C24X0_LCD_BASE 0x4D000000
#define S3C2410_NAND_BASE 0x4E000000
+#define S3C2440_NAND_BASE 0x4E000000
#define S3C24X0_UART_BASE 0x50000000
#define S3C24X0_TIMER_BASE 0x51000000
#define S3C24X0_USB_DEVICE_BASE 0x52000140
@@ -98,11 +99,16 @@
{
return (struct s3c24x0_lcd *)S3C24X0_LCD_BASE;
}
-
+/*
static inline struct s3c2410_nand *s3c2410_get_base_nand(void)
{
return (struct s3c2410_nand *)S3C2410_NAND_BASE;
}
+*/
+static inline struct s3c2440_nand *s3c2440_get_base_nand(void)
+{
+ return (struct s3c2440_nand *)S3C2440_NAND_BASE;
+}

static inline struct s3c24x0_uart
*s3c24x0_get_base_uart(enum s3c24x0_uarts_nr n)
diff -urNwB u-boot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h uboot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h
--- u-boot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/include/asm/arch-s3c24x0/s3c24x0.h 2012-05-09 21:14:35.436230178 +0800
@@ -122,6 +122,7 @@
u32 CLKCON;
u32 CLKSLOW;
u32 CLKDIVN;
+ u32 CAMDIVN;
};

@@ -151,6 +152,7 @@

/* NAND FLASH (see S3C2410 manual chapter 6) */
+/*
struct s3c2410_nand {
u32 NFCONF;
u32 NFCMD;
@@ -159,6 +161,26 @@
u32 NFSTAT;
u32 NFECC;
};
+*/
+
+typedef struct s3c2440_nand{
+ u32 NFCONF;
+ u32 NFCONT;
+ u32 NFCMD;
+ u32 NFADDR;
+ u32 NFDATA;
+ u32 NFMECCD0;
+ u32 NFMECCD1;
+ u32 NFSECCD;
+ u32 NFSTAT;
+ u32 NFESTAT0;
+ u32 NFESTAT1;
+ u32 NFMECC0;
+ u32 NFMECC1;
+ u32 NFSECC;
+ u32 NFSBLK;
+ u32 NFEBLK;
+} S3C2440_NAND;

/* UART (see manual chapter 11) */
diff -urNwB u-boot-2010.06/arch/arm/include/asm/mach-types.h uboot-2010.06/arch/arm/include/asm/mach-types.h
--- u-boot-2010.06/arch/arm/include/asm/mach-types.h 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/include/asm/mach-types.h 2012-05-09 21:16:16.939787902 +0800
@@ -372,7 +372,7 @@
#define MACH_TYPE_IXP421_DNAEETH 359
#define MACH_TYPE_POCKETSERV9200 360
#define MACH_TYPE_TOTO 361
-#define MACH_TYPE_S3C2440 362
+#define MACH_TYPE_S3C2440 168
#define MACH_TYPE_KS8695P 363
#define MACH_TYPE_SE4000 364
#define MACH_TYPE_QUADRICEPS 365
diff -urNwB u-boot-2010.06/arch/arm/lib/board.c uboot-2010.06/arch/arm/lib/board.c
--- u-boot-2010.06/arch/arm/lib/board.c 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/arch/arm/lib/board.c 2012-05-09 21:14:35.437176216 +0800
@@ -173,7 +173,7 @@
for (i=0; i<CONFIG_NR_DRAM_BANKS; i++) {
size += gd->bd->bi_dram[i].size;
}
- puts("DRAM: ");
+ puts("TQ2440 DRAM: ");
print_size(size, "\n");
#endif

@@ -183,7 +183,7 @@
#ifndef CONFIG_SYS_NO_FLASH
static void display_flash_config (ulong size)
{
- puts ("Flash: ");
+ puts ("TQ2440 Flash: ");
print_size (size, "\n");
}
#endif /* CONFIG_SYS_NO_FLASH */
diff -urNwB u-boot-2010.06/board/samsung/tq2440/config.mk uboot-2010.06/board/samsung/tq2440/config.mk
--- u-boot-2010.06/board/samsung/tq2440/config.mk 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/board/samsung/tq2440/config.mk 2012-05-09 21:14:35.437176216 +0800
@@ -0,0 +1,26 @@
+#
+# (C) Copyright 2002
+# Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+# David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
+#
+# SAMSUNG SMDK2410 board with S3C2410X (ARM920T) cpu
+#
+# see http://www.samsung.com/ for more information on SAMSUNG
+#
+
+#
+# SMDK2410 has 1 bank of 64 MB DRAM
+#
+# 3000'0000 to 3400'0000
+#
+# Linux-Kernel is expected to be at 3000'8000, entry 3000'8000
+# optionally with a ramdisk at 3080'0000
+#
+# we load ourself to 33F8'0000
+#
+# download area is 3300'0000
+#
+
+
+TEXT_BASE = 0x33000000
+//TEXT_BASE = 0x33F80000
diff -urNwB u-boot-2010.06/board/samsung/tq2440/flash.c uboot-2010.06/board/samsung/tq2440/flash.c
--- u-boot-2010.06/board/samsung/tq2440/flash.c 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/board/samsung/tq2440/flash.c 2012-05-09 21:14:35.437176216 +0800
@@ -0,0 +1,433 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.de>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+ulong myflush (void);
+
+
+#define FLASH_BANK_SIZE PHYS_FLASH_SIZE
+#define MAIN_SECT_SIZE 0x10000 /* 64 KB */
+
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+
+
+#define CMD_READ_ARRAY 0x000000F0
+#define CMD_UNLOCK1 0x000000AA
+#define CMD_UNLOCK2 0x00000055
+#define CMD_ERASE_SETUP 0x00000080
+#define CMD_ERASE_CONFIRM 0x00000030
+#define CMD_PROGRAM 0x000000A0
+#define CMD_UNLOCK_BYPASS 0x00000020
+
+#define MEM_FLASH_ADDR1 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x00000555 << 1)))
+#define MEM_FLASH_ADDR2 (*(volatile u16 *)(CONFIG_SYS_FLASH_BASE + (0x000002AA << 1)))
+
+#define BIT_ERASE_DONE 0x00000080
+#define BIT_RDY_MASK 0x00000080
+#define BIT_PROGRAM_ERROR 0x00000020
+#define BIT_TIMEOUT 0x80000000 /* our flag */
+
+#define READY 1
+#define ERR 2
+#define TMO 4
+
+/*-----------------------------------------------------------------------
+ */
+
+ulong flash_init (void)
+{
+ int i, j;
+ ulong size = 0;
+
+ for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
+ ulong flashbase = 0;
+
+ flash_info[i].flash_id =
+#if defined(CONFIG_AMD_LV400)
+ (AMD_MANUFACT & FLASH_VENDMASK) |
+ (AMD_ID_LV400B & FLASH_TYPEMASK);
+#elif defined(CONFIG_AMD_LV800)
+ (AMD_MANUFACT & FLASH_VENDMASK) |
+ (AMD_ID_LV800B & FLASH_TYPEMASK);
+#else
+#error "Unknown flash configured"
+#endif
+ flash_info[i].size = FLASH_BANK_SIZE;
+ flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
+ memset (flash_info[i].protect, 0, CONFIG_SYS_MAX_FLASH_SECT);
+ if (i == 0)
+ flashbase = PHYS_FLASH_1;
+ else
+ panic ("configured too many flash banks!\n");
+ for (j = 0; j < flash_info[i].sector_count; j++) {
+ if (j <= 3) {
+ /* 1st one is 16 KB */
+ if (j == 0) {
+ flash_info[i].start[j] =
+ flashbase + 0;
+ }
+
+ /* 2nd and 3rd are both 8 KB */
+ if ((j == 1) || (j == 2)) {
+ flash_info[i].start[j] =
+ flashbase + 0x4000 + (j -
+ 1) *
+ 0x2000;
+ }
+
+ /* 4th 32 KB */
+ if (j == 3) {
+ flash_info[i].start[j] =
+ flashbase + 0x8000;
+ }
+ } else {
+ flash_info[i].start[j] =
+ flashbase + (j - 3) * MAIN_SECT_SIZE;
+ }
+ }
+ size += flash_info[i].size;
+ }
+
+ flash_protect (FLAG_PROTECT_SET,
+ CONFIG_SYS_FLASH_BASE,
+ CONFIG_SYS_FLASH_BASE + monitor_flash_len - 1,
+ &flash_info[0]);
+
+ flash_protect (FLAG_PROTECT_SET,
+ CONFIG_ENV_ADDR,
+ CONFIG_ENV_ADDR + CONFIG_ENV_SIZE - 1, &flash_info[0]);
+
+ return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+ int i;
+
+ switch (info->flash_id & FLASH_VENDMASK) {
+ case (AMD_MANUFACT & FLASH_VENDMASK):
+ printf ("AMD: ");
+ break;
+ default:
+ printf ("Unknown Vendor ");
+ break;
+ }
+
+ switch (info->flash_id & FLASH_TYPEMASK) {
+ case (AMD_ID_LV400B & FLASH_TYPEMASK):
+ printf ("1x Amd29LV400BB (4Mbit)\n");
+ break;
+ case (AMD_ID_LV800B & FLASH_TYPEMASK):
+ printf ("1x Amd29LV800BB (8Mbit)\n");
+ break;
+ default:
+ printf ("Unknown Chip Type\n");
+ goto Done;
+ break;
+ }
+
+ printf (" Size: %ld MB in %d Sectors\n",
+ info->size >> 20, info->sector_count);
+
+ printf (" Sector Start Addresses:");
+ for (i = 0; i < info->sector_count; i++) {
+ if ((i % 5) == 0) {
+ printf ("\n ");
+ }
+ printf (" %08lX%s", info->start[i],
+ info->protect[i] ? " (RO)" : " ");
+ }
+ printf ("\n");
+
+ Done:;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+ ushort result;
+ int iflag, cflag, prot, sect;
+ int rc = ERR_OK;
+ int chip;
+
+ /* first look for protection bits */
+
+ if (info->flash_id == FLASH_UNKNOWN)
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if ((s_first < 0) || (s_first > s_last)) {
+ return ERR_INVAL;
+ }
+
+ if ((info->flash_id & FLASH_VENDMASK) !=
+ (AMD_MANUFACT & FLASH_VENDMASK)) {
+ return ERR_UNKNOWN_FLASH_VENDOR;
+ }
+
+ prot = 0;
+ for (sect = s_first; sect <= s_last; ++sect) {
+ if (info->protect[sect]) {
+ prot++;
+ }
+ }
+ if (prot)
+ return ERR_PROTECTED;
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ cflag = icache_status ();
+ icache_disable ();
+ iflag = disable_interrupts ();
+
+ /* Start erase on unprotected sectors */
+ for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+ printf ("Erasing sector %2d ... ", sect);
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ if (info->protect[sect] == 0) { /* not protected */
+ vu_short *addr = (vu_short *) (info->start[sect]);
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ *addr = CMD_ERASE_CONFIRM;
+
+ /* wait until flash is ready */
+ chip = 0;
+
+ do {
+ result = *addr;
+
+ /* check timeout */
+ if (get_timer_masked () >
+ CONFIG_SYS_FLASH_ERASE_TOUT) {
+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+ chip = TMO;
+ break;
+ }
+
+ if (!chip
+ && (result & 0xFFFF) & BIT_ERASE_DONE)
+ chip = READY;
+
+ if (!chip
+ && (result & 0xFFFF) & BIT_PROGRAM_ERROR)
+ chip = ERR;
+
+ } while (!chip);
+
+ MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+
+ if (chip == ERR) {
+ rc = ERR_PROG_ERROR;
+ goto outahere;
+ }
+ if (chip == TMO) {
+ rc = ERR_TIMOUT;
+ goto outahere;
+ }
+
+ printf ("ok.\n");
+ } else { /* it was protected */
+
+ printf ("protected!\n");
+ }
+ }
+
+ if (ctrlc ())
+ printf ("User Interrupt!\n");
+
+ outahere:
+ /* allow flash to settle - wait 10 ms */
+ udelay_masked (10000);
+
+ if (iflag)
+ enable_interrupts ();
+
+ if (cflag)
+ icache_enable ();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+static int write_hword (flash_info_t * info, ulong dest, ushort data)
+{
+ vu_short *addr = (vu_short *) dest;
+ ushort result;
+ int rc = ERR_OK;
+ int cflag, iflag;
+ int chip;
+
+ /*
+ * Check if Flash is (sufficiently) erased
+ */
+ result = *addr;
+ if ((result & data) != data)
+ return ERR_NOT_ERASED;
+
+
+ /*
+ * Disable interrupts which might cause a timeout
+ * here. Remember that our exception vectors are
+ * at address 0 in the flash, and we don't want a
+ * (ticker) exception to happen while the flash
+ * chip is in programming mode.
+ */
+ cflag = icache_status ();
+ icache_disable ();
+ iflag = disable_interrupts ();
+
+ MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+ MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+ MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
+ *addr = CMD_PROGRAM;
+ *addr = data;
+
+ /* arm simple, non interrupt dependent timer */
+ reset_timer_masked ();
+
+ /* wait until flash is ready */
+ chip = 0;
+ do {
+ result = *addr;
+
+ /* check timeout */
+ if (get_timer_masked () > CONFIG_SYS_FLASH_ERASE_TOUT) {
+ chip = ERR | TMO;
+ break;
+ }
+ if (!chip && ((result & 0x80) == (data & 0x80)))
+ chip = READY;
+
+ if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
+ result = *addr;
+
+ if ((result & 0x80) == (data & 0x80))
+ chip = READY;
+ else
+ chip = ERR;
+ }
+
+ } while (!chip);
+
+ *addr = CMD_READ_ARRAY;
+
+ if (chip == ERR || *addr != data)
+ rc = ERR_PROG_ERROR;
+
+ if (iflag)
+ enable_interrupts ();
+
+ if (cflag)
+ icache_enable ();
+
+ return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+ ulong cp, wp;
+ int l;
+ int i, rc;
+ ushort data;
+
+ wp = (addr & ~1); /* get lower word aligned address */
+
+ /*
+ * handle unaligned start bytes
+ */
+ if ((l = addr - wp) != 0) {
+ data = 0;
+ for (i = 0, cp = wp; i < l; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+ for (; i < 2 && cnt > 0; ++i) {
+ data = (data >> 8) | (*src++ << 8);
+ --cnt;
+ ++cp;
+ }
+ for (; cnt == 0 && i < 2; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+
+ if ((rc = write_hword (info, wp, data)) != 0) {
+ return (rc);
+ }
+ wp += 2;
+ }
+
+ /*
+ * handle word aligned part
+ */
+ while (cnt >= 2) {
+ data = *((vu_short *) src);
+ if ((rc = write_hword (info, wp, data)) != 0) {
+ return (rc);
+ }
+ src += 2;
+ wp += 2;
+ cnt -= 2;
+ }
+
+ if (cnt == 0) {
+ return ERR_OK;
+ }
+
+ /*
+ * handle unaligned tail bytes
+ */
+ data = 0;
+ for (i = 0, cp = wp; i < 2 && cnt > 0; ++i, ++cp) {
+ data = (data >> 8) | (*src++ << 8);
+ --cnt;
+ }
+ for (; i < 2; ++i, ++cp) {
+ data = (data >> 8) | (*(uchar *) cp << 8);
+ }
+
+ return write_hword (info, wp, data);
+}
diff -urNwB u-boot-2010.06/board/samsung/tq2440/lowlevel_init.S uboot-2010.06/board/samsung/tq2440/lowlevel_init.S
--- u-boot-2010.06/board/samsung/tq2440/lowlevel_init.S 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/board/samsung/tq2440/lowlevel_init.S 2012-05-09 21:14:35.437176216 +0800
@@ -0,0 +1,167 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ * Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * Modified for the Samsung SMDK2410 by
+ * (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
+ */
+
+
+#include <config.h>
+#include <version.h>
+
+
+/* some parameters for the board */
+
+/*
+ *
+ * Taken from linux/arch/arm/boot/compressed/head-s3c2410.S
+ *
+ * Copyright (C) 2002 Samsung Electronics SW.LEE <hitchcar@sec.samsung.com>
+ *
+ */
+
+#define BWSCON 0x48000000
+
+/* BWSCON */
+#define DW8 (0x0)
+#define DW16 (0x1)
+#define DW32 (0x2)
+#define WAIT (0x1<<2)
+#define UBLB (0x1<<3)
+
+#define B1_BWSCON (DW16)
+#define B2_BWSCON (DW16)
+#define B3_BWSCON (DW16 + WAIT + UBLB)
+#define B4_BWSCON (DW16)
+#define B5_BWSCON (DW8)
+#define B6_BWSCON (DW32)
+#define B7_BWSCON (DW32)
+
+/* BANK0CON */
+#define B0_Tacs 0x0 /* 0clk */
+#define B0_Tcos 0x0 /* 0clk */
+#define B0_Tacc 0x7 /* 14clk */
+#define B0_Tcoh 0x0 /* 0clk */
+#define B0_Tah 0x0 /* 0clk */
+#define B0_Tacp 0x0
+#define B0_PMC 0x0 /* normal */
+
+/* BANK1CON */
+#define B1_Tacs 0x0 /* 0clk */
+#define B1_Tcos 0x0 /* 0clk */
+#define B1_Tacc 0x7 /* 14clk */
+#define B1_Tcoh 0x0 /* 0clk */
+#define B1_Tah 0x0 /* 0clk */
+#define B1_Tacp 0x0
+#define B1_PMC 0x0
+
+#define B2_Tacs 0x0
+#define B2_Tcos 0x0
+#define B2_Tacc 0x7
+#define B2_Tcoh 0x0
+#define B2_Tah 0x0
+#define B2_Tacp 0x0
+#define B2_PMC 0x0
+
+#define B3_Tacs 0x0 /* 0clk */
+#define B3_Tcos 0x3 /* 4clk */
+#define B3_Tacc 0x7 /* 14clk */
+#define B3_Tcoh 0x1 /* 1clk */
+#define B3_Tah 0x0 /* 0clk */
+#define B3_Tacp 0x3 /* 6clk */
+#define B3_PMC 0x0 /* normal */
+
+#define B4_Tacs 0x0 /* 0clk */
+#define B4_Tcos 0x0 /* 0clk */
+#define B4_Tacc 0x7 /* 14clk */
+#define B4_Tcoh 0x0 /* 0clk */
+#define B4_Tah 0x0 /* 0clk */
+#define B4_Tacp 0x0
+#define B4_PMC 0x0 /* normal */
+
+#define B5_Tacs 0x0 /* 0clk */
+#define B5_Tcos 0x0 /* 0clk */
+#define B5_Tacc 0x7 /* 14clk */
+#define B5_Tcoh 0x0 /* 0clk */
+#define B5_Tah 0x0 /* 0clk */
+#define B5_Tacp 0x0
+#define B5_PMC 0x0 /* normal */
+
+#define B6_MT 0x3 /* SDRAM */
+#define B6_Trcd 0x1
+#define B6_SCAN 0x1 /* 9bit */
+
+#define B7_MT 0x3 /* SDRAM */
+#define B7_Trcd 0x1 /* 3clk */
+#define B7_SCAN 0x1 /* 9bit */
+
+/* REFRESH parameter */
+#define REFEN 0x1 /* Refresh enable */
+#define TREFMD 0x0 /* CBR(CAS before RAS)/Auto refresh */
+#define Trp 0x0 /* 2clk */
+#define Trc 0x3 /* 7clk */
+#define Tchr 0x2 /* 3clk */
+#define REFCNT 0x4f4 /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */
+/**************************************/
+
+_TEXT_BASE:
+ .word TEXT_BASE
+
+.globl lowlevel_init
+lowlevel_init:
+ /* memory control configuration */
+ /* make r0 relative the current location so that it */
+ /* reads SMRDATA out of FLASH rather than memory ! */
+ ldr r0, =SMRDATA
+ ldr r1, _TEXT_BASE
+ sub r0, r0, r1
+ ldr r1, =BWSCON /* Bus Width Status Controller */
+ add r2, r0, #13*4
+0:
+ ldr r3, [r0], #4
+ str r3, [r1], #4
+ cmp r2, r0
+ bne 0b
+
+ /* everything is fine now */
+ mov pc, lr
+
+ .ltorg
+/* the literal pools origin */
+
+SMRDATA:
+ .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
+ .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
+ .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
+ .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
+ .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
+ .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
+ .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
+ .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
+ .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
+ .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
+ .word 0x32
+ .word 0x30
+ .word 0x30
diff -urNwB u-boot-2010.06/board/samsung/tq2440/Makefile uboot-2010.06/board/samsung/tq2440/Makefile
--- u-boot-2010.06/board/samsung/tq2440/Makefile 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/board/samsung/tq2440/Makefile 2012-05-09 21:14:35.437176216 +0800
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd@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 := tq2440.o flash.o nand_start.o
+SOBJS := lowlevel_init.o
+
+SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS := $(addprefix $(obj),$(COBJS))
+SOBJS := $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+ $(AR) $(ARFLAGS) $@ $(OBJS) $(SOBJS)
+
+clean:
+ rm -f $(SOBJS) $(OBJS)
+
+distclean: clean
+ rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff -urNwB u-boot-2010.06/board/samsung/tq2440/nand_start.c uboot-2010.06/board/samsung/tq2440/nand_start.c
--- u-boot-2010.06/board/samsung/tq2440/nand_start.c 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/board/samsung/tq2440/nand_start.c 2012-05-09 21:14:35.437176216 +0800
@@ -0,0 +1,435 @@
+#include <common.h>
+//#include <s3c2410.h>
+#include <asm/arch/s3c24x0_cpu.h>
+
+#define GSTATUS1 (*(volatile unsigned int *)0x560000B0)
+#define BUSY 1
+
+#define NAND_SECTOR_SIZE 512
+#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
+
+#define NAND_SECTOR_SIZE_LP 2048
+#define NAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)
+
+char bLARGEBLOCK; //HJ_add 20090807
+char b128MB; //HJ_add 20090807
+
+/* 供外部调用的函数 */
+void nand_init_ll(void);
+int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size);
+int nand_read_ll_lp(unsigned char *buf, unsigned long start_addr, int size);
+
+/* NAND Flash操作的总入口, 它们将调用S3C2410或S3C2440的相应函数 */
+static void nand_reset(void);
+static void wait_idle(void);
+static void nand_select_chip(void);
+static void nand_deselect_chip(void);
+static void write_cmd(int cmd);
+static void write_addr(unsigned int addr);
+static void write_addr_lp(unsigned int addr);
+static unsigned char read_data(void);
+int NF_ReadID(void); //HJ_add 20090807
+
+/* S3C2440的NAND Flash处理函数 */
+static void s3c2440_nand_reset(void);
+static void s3c2440_wait_idle(void);
+static void s3c2440_nand_select_chip(void);
+static void s3c2440_nand_deselect_chip(void);
+static void s3c2440_write_cmd(int cmd);
+static void s3c2440_write_addr(unsigned int addr);
+static void s3c2440_write_addr_lp(unsigned int addr);
+static unsigned char s3c2440_read_data(void);
+
+/* S3C2440的NAND Flash操作函数 */
+
+/* 复位 */
+static void s3c2440_nand_reset(void)
+{
+ s3c2440_nand_select_chip();
+ s3c2440_write_cmd(0xff); // 复位命令
+ s3c2440_wait_idle();
+ s3c2440_nand_deselect_chip();
+}
+
+/* 等待NAND Flash就绪 */
+static void s3c2440_wait_idle(void)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;
+
+ while(!(*p & BUSY))
+ for(i=0; i<10; i++);
+}
+
+/* 发出片选信号 */
+static void s3c2440_nand_select_chip(void)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+
+ s3c2440nand->NFCONT &= ~(1<<1);
+ for(i=0; i<10; i++);
+}
+
+/* 取消片选信号 */
+static void s3c2440_nand_deselect_chip(void)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+
+ s3c2440nand->NFCONT |= (1<<1);
+}
+
+/* 发出命令 */
+static void s3c2440_write_cmd(int cmd)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;
+ *p = cmd;
+}
+
+/* 发出地址 */
+static void s3c2440_write_addr(unsigned int addr)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+ *p = addr & 0xff;
+ for(i=0; i<10; i++);
+ *p = (addr >> 9) & 0xff;
+ for(i=0; i<10; i++);
+ *p = (addr >> 17) & 0xff;
+ for(i=0; i<10; i++);
+ *p = (addr >> 25) & 0xff;
+ for(i=0; i<10; i++);
+}
+
+
+/* 发出地址 */
+static void s3c2440_write_addr_lp(unsigned int addr)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+ int col, page;
+
+ col = addr & NAND_BLOCK_MASK_LP;
+ page = addr / NAND_SECTOR_SIZE_LP;
+
+ *p = col & 0xff; /* Column Address A0~A7 */
+ for(i=0; i<10; i++);
+ *p = (col >> 8) & 0x0f; /* Column Address A8~A11 */
+ for(i=0; i<10; i++);
+ *p = page & 0xff; /* Row Address A12~A19 */
+ for(i=0; i<10; i++);
+ *p = (page >> 8) & 0xff; /* Row Address A20~A27 */
+ for(i=0; i<10; i++);
+if (b128MB == 0)
+ *p = (page >> 16) & 0x03; /* Row Address A28~A29 */
+ for(i=0; i<10; i++);
+}
+
+/* 读取数据 */
+static unsigned char s3c2440_read_data(void)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;
+ return *p;
+}
+
+
+/* 在第一次使用NAND Flash前,复位一下NAND Flash */
+static void nand_reset(void)
+{
+ s3c2440_nand_reset();
+}
+
+static void wait_idle(void)
+{
+ s3c2440_wait_idle();
+}
+
+static void nand_select_chip(void)
+{
+ int i;
+
+ s3c2440_nand_select_chip();
+
+ for(i=0; i<10; i++);
+}
+
+static void nand_deselect_chip(void)
+{
+ s3c2440_nand_deselect_chip();
+}
+
+static void write_cmd(int cmd)
+{
+ s3c2440_write_cmd(cmd);
+}
+static void write_addr(unsigned int addr)
+{
+ s3c2440_write_addr(addr);
+}
+
+static void write_addr_lp(unsigned int addr)
+{
+ s3c2440_write_addr_lp(addr);
+}
+
+static unsigned char read_data(void)
+{
+ return s3c2440_read_data();
+}
+
+/* 初始化NAND Flash */
+void nand_init_ll(void)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+
+ #define TACLS 0
+ #define TWRPH0 3
+ #define TWRPH1 0
+
+ /* 设置时序 */
+ s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
+ /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
+ s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);
+
+ /* 复位NAND Flash */
+ nand_reset();
+}
+#if 1
+int NF_ReadID(void)
+{
+ char pMID;
+ char pDID;
+ int nBuff;
+ char n4thcycle;
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+ b128MB = 1;
+ n4thcycle = nBuff = 0;
+
+ nand_init_ll();
+ nand_select_chip();
+ write_cmd(0x90); // read id command
+ *p=0x00 & 0xff;
+ for ( i = 0; i < 100; i++ );
+
+ pMID = read_data();
+ pDID = read_data();
+ nBuff = read_data();
+ n4thcycle = read_data();
+
+ nand_deselect_chip();
+
+ if (pDID >= 0xA0)
+ {
+ b128MB = 0;
+ }
+
+ return (pDID);
+}
+#endif
+
+/* 读函数 */
+int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
+{
+ int i, j;
+ char dat;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+
+ if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
+ {
+ return -1; /* 地址或长度不对齐 */
+ }
+
+ /* 选中芯片 */
+ nand_select_chip();
+
+ for(i=start_addr; i < (start_addr + size);)
+ {
+/* Check Bad Block */
+if(1){
+ /* 发出READ0命令 */
+ write_cmd(0x50);
+
+ *p = 5;
+ for(j=0; j<10; j++);
+ *p = (i >> 9) & 0xff;
+ for(j=0; j<10; j++);
+ *p = (i >> 17) & 0xff;
+ for(j=0; j<10; j++);
+ *p = (i >> 25) & 0xff;
+ for(j=0; j<10; j++);
+ wait_idle();
+ dat = read_data();
+ write_cmd(0);
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+ if(dat != 0xff)
+ i += 16384; // 1 Block = 512*32= 16384
+/* Read Page */
+ /* 选中芯片 */
+ nand_select_chip();
+}
+ /* 发出READ0命令 */
+ write_cmd(0);
+
+ /* Write Address */
+ write_addr(i);
+ wait_idle();
+
+ for(j=0; j < NAND_SECTOR_SIZE; j++, i++)
+ {
+ *buf = read_data();
+ buf++;
+ }
+ }
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+
+ return 0;
+}
+
+/* 读函数
+ * Large Page
+ */
+int nand_read_ll_lp(unsigned char *buf, unsigned long start_addr, int size)
+{
+ int i, j;
+ char dat;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+ if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP))
+ {
+ return -1; /* 地址或长度不对齐 */
+ }
+
+ /* 选中芯片 */
+ nand_select_chip();
+
+ for(i=start_addr; i < (start_addr + size);)
+ {
+/* Check Bad Block */
+if(1){
+ int col, page;
+
+ col = i & NAND_BLOCK_MASK_LP;
+ page = i / NAND_SECTOR_SIZE_LP;
+ /* 发出READ0命令 */
+ write_cmd(0x00);
+
+ *p = 5;
+ for(j=0; j<10; j++);
+ *p = 8;
+ for(j=0; j<10; j++);
+ *p = page & 0xff; /* Row Address A12~A19 */
+ for(j=0; j<10; j++);
+ *p = (page >> 8) & 0xff; /* Row Address A20~A27 */
+ for(j=0; j<10; j++);
+if (b128MB == 0)
+ *p = (page >> 16) & 0x03; /* Row Address A28~A29 */
+ for(j=0; j<10; j++);
+
+ write_cmd(0x30);
+ wait_idle();
+ dat = read_data();
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+ if(dat != 0xff)
+ i += 131072; // 1 Block = 2048*64= 131072
+/* Read Page */
+ /* 选中芯片 */
+ nand_select_chip();
+}
+ /* 发出READ0命令 */
+ write_cmd(0);
+
+ /* Write Address */
+ write_addr_lp(i);
+ write_cmd(0x30);
+ wait_idle();
+
+ for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++)
+ {
+ *buf = read_data();
+ buf++;
+ }
+ }
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+
+ return 0;
+}
+
+int bBootFrmNORFlash(void)
+{
+ volatile unsigned int *pdw = (volatile unsigned int *)0;
+ unsigned int dwVal;
+
+ /*
+ * 无论是从NOR Flash还是从NAND Flash启动,
+ * 地址0处为指令"b Reset", 机器码为0xEA00000B,
+ * 对于从NAND Flash启动的情况,其开始4KB的代码会复制到CPU内部4K内存中,
+ * 对于从NOR Flash启动的情况,NOR Flash的开始地址即为0。
+ * 对于NOR Flash,必须通过一定的命令序列才能写数据,
+ * 所以可以根据这点差别来分辨是从NAND Flash还是NOR Flash启动:
+ * 向地址0写入一个数据,然后读出来,如果没有改变的话就是NOR Flash
+ */
+
+ dwVal = *pdw;
+ *pdw = 0x12345678;
+ if (*pdw != 0x12345678)
+ {
+ return 1;
+ }
+ else
+ {
+ *pdw = dwVal;
+ return 0;
+ }
+}
+
+int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
+{
+ unsigned int *pdwDest;
+ unsigned int *pdwSrc;
+ int i;
+
+ if (bBootFrmNORFlash())
+ {
+ pdwDest = (unsigned int *)buf;
+ pdwSrc = (unsigned int *)start_addr;
+ /* 从 NOR Flash启动 */
+ for (i = 0; i < size / 4; i++)
+ {
+ pdwDest[i] = pdwSrc[i];
+ }
+ return 0;
+ }
+ else
+ {
+ /* 初始化NAND Flash */
+ nand_init_ll();
+
+ /* 从 NAND Flash启动 */
+ if (NF_ReadID() == 0x76 )
+ nand_read_ll(buf, start_addr, (size + NAND_BLOCK_MASK)&~(NAND_BLOCK_MASK));
+ else
+ nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
+ return 0;
+ }
+}
diff -urNwB u-boot-2010.06/board/samsung/tq2440/nand_start_new.c uboot-2010.06/board/samsung/tq2440/nand_start_new.c
--- u-boot-2010.06/board/samsung/tq2440/nand_start_new.c 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/board/samsung/tq2440/nand_start_new.c 2012-05-09 21:14:35.439153337 +0800
@@ -0,0 +1,468 @@
+#include <common.h>
+//#include <s3c2410.h>
+#include <asm/arch/s3c24x0_cpu.h>
+#include <asm/io.h>
+
+#define GSTATUS1 (*(volatile unsigned int *)0x560000B0)
+#define BUSY 1
+
+#define NAND_SECTOR_SIZE 512
+#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)
+
+#define NAND_SECTOR_SIZE_LP 2048
+#define NAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)
+
+char bLARGEBLOCK; //HJ_add 20090807
+char b128MB; //HJ_add 20090807
+
+/* 供外部调用的函数 */
+void nand_init_ll(void);
+int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size);
+int nand_read_ll_lp(unsigned char *buf, unsigned long start_addr, int size);
+
+/* NAND Flash操作的总入口, 它们将调用S3C2410或S3C2440的相应函数 */
+static void nand_reset(void);
+static void wait_idle(void);
+static void nand_select_chip(void);
+static void nand_deselect_chip(void);
+static void write_cmd(int cmd);
+static void write_addr(unsigned int addr);
+static void write_addr_lp(unsigned int addr);
+static unsigned char read_data(void);
+int NF_ReadID(void); //HJ_add 20090807
+
+/* S3C2440的NAND Flash处理函数 */
+static void s3c2440_nand_reset(void);
+static void s3c2440_wait_idle(void);
+static void s3c2440_nand_select_chip(void);
+static void s3c2440_nand_deselect_chip(void);
+static void s3c2440_write_cmd(int cmd);
+static void s3c2440_write_addr(unsigned int addr);
+static void s3c2440_write_addr_lp(unsigned int addr);
+static unsigned char s3c2440_read_data(void);
+
+/* S3C2440的NAND Flash操作函数 */
+
+/* 复位 */
+static void s3c2440_nand_reset(void)
+{
+ s3c2440_nand_select_chip();
+ s3c2440_write_cmd(0xff); // 复位命令
+ s3c2440_wait_idle();
+ s3c2440_nand_deselect_chip();
+}
+
+/* 等待NAND Flash就绪 */
+static void s3c2440_wait_idle(void)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;
+
+ //while(!(*p & BUSY))
+ while(!(readb(&s3c2440nand->NFSTAT) & BUSY))
+ for(i=0; i<10; i++);
+}
+
+/* 发出片选信号 */
+static void s3c2440_nand_select_chip(void)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+
+ //s3c2440nand->NFCONT &= ~(1<<1);
+ writel(readl(&s3c2440nand->NFCONT) & ~(1<<1),&s3c2440nand->NFCONT);
+ for(i=0; i<10; i++);
+}
+
+/* 取消片选信号 */
+static void s3c2440_nand_deselect_chip(void)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+
+ //s3c2440nand->NFCONT |= (1<<1);
+ writel(readl(&s3c2440nand->NFCONT) | (1<<1),&s3c2440nand->NFCONT);
+}
+
+/* 发出命令 */
+static void s3c2440_write_cmd(int cmd)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;
+ //*p = cmd;
+ writeb(cmd,&s3c2440nand->NFCMD);
+}
+
+/* 发出地址 */
+static void s3c2440_write_addr(unsigned int addr)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+ //*p = addr & 0xff;
+ writeb(addr & 0xff,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+ //*p = (addr >> 9) & 0xff;
+ writeb((addr >> 9) & 0xff,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+ //*p = (addr >> 17) & 0xff;
+ writeb((addr >> 17) & 0xff,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+ //*p = (addr >> 25) & 0xff;
+ writeb((addr >> 25) & 0xff,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+}
+
+
+/* 发出地址 */
+static void s3c2440_write_addr_lp(unsigned int addr)
+{
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+ int col, page;
+
+ col = addr & NAND_BLOCK_MASK_LP;
+ page = addr / NAND_SECTOR_SIZE_LP;
+
+ //*p = col & 0xff; /* Column Address A0~A7 */
+ writeb(col & 0xff,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+ //*p = (col >> 8) & 0x0f; /* Column Address A8~A11 */
+ writeb((col >> 8) & 0x0f,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+ //*p = page & 0xff; /* Row Address A12~A19 */
+ writeb(page & 0xff,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+ //*p = (page >> 8) & 0xff; /* Row Address A20~A27 */
+ writeb((page >> 8) & 0xff,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+if (b128MB == 0)
+ //*p = (page >> 16) & 0x03; /* Row Address A28~A29 */
+ writeb((page >> 16) & 0x03,&s3c2440nand->NFADDR);
+ for(i=0; i<10; i++);
+}
+
+/* 读取数据 */
+static unsigned char s3c2440_read_data(void)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;
+ //return *p;
+ return readb(&s3c2440nand->NFDATA);
+}
+
+
+/* 在第一次使用NAND Flash前,复位一下NAND Flash */
+static void nand_reset(void)
+{
+ s3c2440_nand_reset();
+}
+
+static void wait_idle(void)
+{
+ s3c2440_wait_idle();
+}
+
+static void nand_select_chip(void)
+{
+ int i;
+
+ s3c2440_nand_select_chip();
+
+ for(i=0; i<10; i++);
+}
+
+static void nand_deselect_chip(void)
+{
+ s3c2440_nand_deselect_chip();
+}
+
+static void write_cmd(int cmd)
+{
+ s3c2440_write_cmd(cmd);
+}
+static void write_addr(unsigned int addr)
+{
+ s3c2440_write_addr(addr);
+}
+
+static void write_addr_lp(unsigned int addr)
+{
+ s3c2440_write_addr_lp(addr);
+}
+
+static unsigned char read_data(void)
+{
+ return s3c2440_read_data();
+}
+
+/* 初始化NAND Flash */
+void nand_init_ll(void)
+{
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ u_int32_t cfg;
+
+ #define TACLS 0
+ #define TWRPH0 3
+ #define TWRPH1 0
+
+ /* 设置时序 */
+ //s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
+ cfg = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
+ writel(cfg,&s3c2440nand->NFCONF);
+ /* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
+ //s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);
+ cfg = (1<<4)|(1<<1)|(1<<0);
+ writel(cfg,&s3c2440nand->NFCONT);
+ /* 复位NAND Flash */
+ nand_reset();
+}
+#if 1
+int NF_ReadID(void)
+{
+ char pMID;
+ char pDID;
+ int nBuff;
+ char n4thcycle;
+ int i;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+ b128MB = 1;
+ n4thcycle = nBuff = 0;
+
+ nand_init_ll();
+ nand_select_chip();
+ write_cmd(0x90); // read id command
+ //*p=0x00 & 0xff;
+ writeb(0x00 & 0xff,&s3c2440nand->NFADDR);
+ for ( i = 0; i < 100; i++ );
+
+ pMID = read_data();
+ pDID = read_data();
+ nBuff = read_data();
+ n4thcycle = read_data();
+
+ nand_deselect_chip();
+
+ if (pDID >= 0xA0)
+ {
+ b128MB = 0;
+ }
+
+ return (pDID);
+}
+#endif
+
+/* 读函数 */
+int nand_read_ll(unsigned char *buf, unsigned long start_addr, int size)
+{
+ int i, j;
+ char dat;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+
+ if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK))
+ {
+ return -1; /* 地址或长度不对齐 */
+ }
+
+ /* 选中芯片 */
+ nand_select_chip();
+
+ for(i=start_addr; i < (start_addr + size);)
+ {
+/* Check Bad Block */
+if(1){
+ /* 发出READ0命令 */
+ write_cmd(0x50);
+
+ //*p = 5;
+ writeb(5,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+ //*p = (i >> 9) & 0xff;
+ writeb((i >> 9) & 0xff,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+ //*p = (i >> 17) & 0xff;
+ writeb((i >> 17) & 0xff,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+ //*p = (i >> 25) & 0xff;
+ writeb((i >> 25) & 0xff,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+ wait_idle();
+ dat = read_data();
+ write_cmd(0);
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+ if(dat != 0xff)
+ i += 16384; // 1 Block = 512*32= 16384
+/* Read Page */
+ /* 选中芯片 */
+ nand_select_chip();
+}
+ /* 发出READ0命令 */
+ write_cmd(0);
+
+ /* Write Address */
+ write_addr(i);
+ wait_idle();
+
+ for(j=0; j < NAND_SECTOR_SIZE; j++, i++)
+ {
+ *buf = read_data();
+ buf++;
+ }
+ }
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+
+ return 0;
+}
+
+/* 读函数
+ * Large Page
+ */
+int nand_read_ll_lp(unsigned char *buf, unsigned long start_addr, int size)
+{
+ int i, j;
+ char dat;
+ S3C2440_NAND * s3c2440nand = (S3C2440_NAND *)0x4e000000;
+ //volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;
+
+ if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP))
+ {
+ return -1; /* 地址或长度不对齐 */
+ }
+
+ /* 选中芯片 */
+ nand_select_chip();
+
+ for(i=start_addr; i < (start_addr + size);)
+ {
+/* Check Bad Block */
+if(1){
+ int col, page;
+
+ col = i & NAND_BLOCK_MASK_LP;
+ page = i / NAND_SECTOR_SIZE_LP;
+ /* 发出READ0命令 */
+ write_cmd(0x00);
+
+ //*p = 5;
+ writeb(5,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+ //*p = 8;
+ writeb(8,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+ //*p = page & 0xff; /* Row Address A12~A19 */
+ writeb(page & 0xff,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+ //*p = (page >> 8) & 0xff; /* Row Address A20~A27 */
+ writeb((page >> 8) & 0xff,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+if (b128MB == 0)
+ //*p = (page >> 16) & 0x03; /* Row Address A28~A29 */
+ writeb((page >> 16) & 0x03,&s3c2440nand->NFADDR);
+ for(j=0; j<10; j++);
+
+ write_cmd(0x30);
+ wait_idle();
+ dat = read_data();
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+ if(dat != 0xff)
+ i += 131072; // 1 Block = 2048*64= 131072
+/* Read Page */
+ /* 选中芯片 */
+ nand_select_chip();
+}
+ /* 发出READ0命令 */
+ write_cmd(0);
+
+ /* Write Address */
+ write_addr_lp(i);
+ write_cmd(0x30);
+ wait_idle();
+
+ for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++)
+ {
+ *buf = read_data();
+ buf++;
+ }
+ }
+
+ /* 取消片选信号 */
+ nand_deselect_chip();
+
+ return 0;
+}
+
+int bBootFrmNORFlash(void)
+{
+ volatile unsigned int *pdw = (volatile unsigned int *)0;
+ unsigned int dwVal;
+
+ /*
+ * 无论是从NOR Flash还是从NAND Flash启动,
+ * 地址0处为指令"b Reset", 机器码为0xEA00000B,
+ * 对于从NAND Flash启动的情况,其开始4KB的代码会复制到CPU内部4K内存中,
+ * 对于从NOR Flash启动的情况,NOR Flash的开始地址即为0。
+ * 对于NOR Flash,必须通过一定的命令序列才能写数据,
+ * 所以可以根据这点差别来分辨是从NAND Flash还是NOR Flash启动:
+ * 向地址0写入一个数据,然后读出来,如果没有改变的话就是NOR Flash
+ */
+
+ //dwVal = *pdw;
+ dwVal = readl(pdw);
+ //*pdw = 0x12345678;
+ writel(0x12345678,pdw);
+ //if (*pdw != 0x12345678)
+ if (readl(pdw) != 0x12345678)
+ {
+ return 1;
+ }
+ else
+ {
+ //*pdw = dwVal;
+ writel(dwVal,pdw);
+ return 0;
+ }
+}
+
+int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
+{
+ unsigned int *pdwDest;
+ unsigned int *pdwSrc;
+ int i;
+ // printf("IN Copycode2ram\n");
+ if (bBootFrmNORFlash())
+ {
+ pdwDest = (unsigned int *)buf;
+ pdwSrc = (unsigned int *)start_addr;
+ /* 从 NOR Flash启动 */
+ for (i = 0; i < size / 4; i++)
+ {
+ pdwDest[i] = pdwSrc[i];
+ }
+ return 0;
+ }
+ else
+ {
+ /* 初始化NAND Flash */
+ nand_init_ll();
+
+ /* 从 NAND Flash启动 */
+ if (NF_ReadID() == 0x76 )
+ nand_read_ll(buf, start_addr, (size + NAND_BLOCK_MASK)&~(NAND_BLOCK_MASK));
+ else
+ nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
+ return 0;
+ }
+}
diff -urNwB u-boot-2010.06/board/samsung/tq2440/tq2440.c uboot-2010.06/board/samsung/tq2440/tq2440.c
--- u-boot-2010.06/board/samsung/tq2440/tq2440.c 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/board/samsung/tq2440/tq2440.c 2012-05-09 21:14:35.439153337 +0800
@@ -0,0 +1,143 @@
+/*
+ * (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>
+ *
+ * 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 <netdev.h>
+#include <asm/arch/s3c24x0_cpu.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+/*
+#define FCLK_SPEED 1
+
+#if FCLK_SPEED==0 // Fout = 203MHz, Fin = 12MHz for Audio
+#define M_MDIV 0xC3
+#define M_PDIV 0x4
+#define M_SDIV 0x1
+#elif FCLK_SPEED==1 // Fout = 202.8MHz
+#define M_MDIV 0xA1
+#define M_PDIV 0x3
+#define M_SDIV 0x1
+#endif
+
+#define USB_CLOCK 1
+
+#if USB_CLOCK==0
+#define U_M_MDIV 0xA1
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x1
+#elif USB_CLOCK==1
+#define U_M_MDIV 0x48
+#define U_M_PDIV 0x3
+#define U_M_SDIV 0x2
+#endif
+*/
+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
+ */
+
+int board_init (void)
+{
+ struct s3c24x0_clock_power * const clk_power =
+ s3c24x0_get_base_clock_power();
+ struct s3c24x0_gpio * const gpio = s3c24x0_get_base_gpio();
+
+ /* to reduce PLL lock time, adjust the LOCKTIME register */
+ clk_power->LOCKTIME = 0xFFFFFFFF;
+
+ /* configure MPLL */
+ //clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ //delay (4000);
+
+ /* configure UPLL */
+ //clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);
+
+ /* some delay between MPLL and UPLL */
+ //delay (8000);
+
+ /* set up the I/O ports */
+ gpio->GPACON = 0x007FFFFF;
+ gpio->GPBCON = 0x00055555;
+ gpio->GPBUP = 0x000007FF;
+ gpio->GPCCON = 0xAAAAAAAA;
+ gpio->GPCUP = 0x0000FFFF;
+ gpio->GPDCON = 0xAAAAAAAA;
+ gpio->GPDUP = 0x0000FFFF;
+ gpio->GPECON = 0xAAAAAAAA;
+ gpio->GPEUP = 0x0000FFFF;
+ gpio->GPFCON = 0x000055AA;
+ gpio->GPFUP = 0x000000FF;
+ gpio->GPGCON = 0xFF94FFBA;
+ gpio->GPGUP = 0x0000FFFF;
+ gpio->GPGDAT = gpio->GPGDAT & (~(1<<4)) | (1<<4);
+ gpio->GPHCON = 0x002AFAAA;
+ gpio->GPHUP = 0x000007FF;
+
+ /* arch number of SMDK2410-Board */
+ //gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
+ gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
+
+ /* adress of boot parameters */
+ gd->bd->bi_boot_params = 0x30000100;
+
+ icache_enable();
+ dcache_enable();
+
+ return 0;
+}
+
+int dram_init (void)
+{
+ gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
+ gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
+
+ return 0;
+}
+
+#ifdef CONFIG_CMD_NET
+int board_eth_init(bd_t *bis)
+{
+ int rc = 0;
+/*
+#ifdef CONFIG_CS8900
+ rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
+#endif
+*/
+#ifdef CONFIG_DRIVER_DM9000
+ rc = dm9000_initialize(bis);
+#endif
+ return rc;
+}
+#endif
diff -urNwB u-boot-2010.06/common/cmd_hello.c uboot-2010.06/common/cmd_hello.c
--- u-boot-2010.06/common/cmd_hello.c 1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/common/cmd_hello.c 2012-05-09 21:14:35.439153337 +0800
@@ -0,0 +1,30 @@
+#include <common.h>
+#include <watchdog.h>
+#include <command.h>
+#include <image.h>
+#include <malloc.h>
+#include <u-boot/zlib.h>
+#include <bzlib.h>
+#include <environment.h>
+#include <lmb.h>
+#include <linux/ctype.h>
+#include <asm/byteorder.h>
+
+int do_hello (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
+{
+ int i;
+ printf("Hello, argc is %d,you have entered its arg:",argc);
+ for(i=0;i<argc;i++)
+ printf("%s ",argv[i]);
+ printf("\n");
+ return 0;
+}
+
+U_BOOT_CMD(
+ hello,
+ CONFIG_SYS_MAXARGS,
+ 1,
+ do_hello,
+ "hello command ,just for test.",
+ "-long help for hello. usage: hello argv[1] argv[2] ...\n"
+);
diff -urNwB u-boot-2010.06/common/Makefile uboot-2010.06/common/Makefile
--- u-boot-2010.06/common/Makefile 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/common/Makefile 2012-05-09 21:14:35.439153337 +0800
@@ -48,6 +48,8 @@
COBJS-y += cmd_nvedit.o
COBJS-y += cmd_version.o

+COBJS-y += cmd_hello.o
+
# environment
COBJS-y += env_common.o
COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o
diff -urNwB u-boot-2010.06/drivers/mtd/nand/nand_base.c uboot-2010.06/drivers/mtd/nand/nand_base.c
--- u-boot-2010.06/drivers/mtd/nand/nand_base.c 2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/drivers/mtd/nand/nand_base.c 2012-05-09 21:14:35.439153337 +0800
@@ -191,6 +191,7 @@
static uint8_t nand_read_byte(struct mtd_info *mtd)
{
struct nand_chip *chip = mtd->priv;
+ //printf("In nand_read_byte,chip->IO_ADDR_R is %p\n",chip->IO_ADDR_R);
return readb(chip->IO_ADDR_R);
}

@@ -561,6 +562,7 @@
chip->cmd_ctrl(mtd, readcmd, ctrl);
ctrl &= ~NAND_CTRL_CHANGE;
}
+ //printf("In %s,next will call cmd_ctrl.\n",__func__);
chip->cmd_ctrl(mtd, command, ctrl);

/*
@@ -2

抱歉!评论已关闭.