加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 06:14:21 所属栏目:百科 来源:网络整理
导读:?? 将本文件中的内容对uboot-2010.06源码打补丁,之后再编译,生成uboot.bin就可以直接在TQ2440开发板运行了(使用天嵌光盘自带的内核源码配置单,做出uImage)。 diff -urNwB u-boot-2010.06/arch/arm/cpu/arm920t/s3c24x0/Makefile uboot-2010.06/arch/arm

?? 将本文件中的内容对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%02xn",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%xn",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%02xn",+	       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 implementedn");
+	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_initn");
+
+	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 = %luMHzn",+	       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,r1,c1,c0,0 /*Asynchronous.read ctrl register*/
+	orr r1,#0xc0000000      /*Asynchronous*/
+	mcr p15,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,=GPBDAT
+	ldr r1,=0x1C0
+	str r1,[r0]
+#endif
+/********************************************************************/
+
+stack_setup:
+	ldr	r0,_TEXT_BASE		/* upper 128 KiB: relocated uboot   */
+	sub	r0,#CONFIG_SYS_MALLOC_LEN	/* malloc area              */
+	sub	r0,#CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
+#ifdef CONFIG_USE_IRQ
+	sub	r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
+#endif
+	sub	sp,#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,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,#CONFIG_SYS_MALLOC_LEN	/* malloc area              */
-	sub	r0,#CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
-#ifdef CONFIG_USE_IRQ
-	sub	r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
-#endif
-	sub	sp,#12		/* leave 3 words for abort-stack    */
-	bic	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,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,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,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 Typen");
+		goto Done;
+		break;
+	}
+
+	printf ("  Size: %ld MB in %d Sectorsn",+		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,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,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,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,<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,+ * 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,r1
+	ldr	r1,=BWSCON	/* Bus Width Status Controller */
+	add     r2,#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,51 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk,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,+# 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,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,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,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,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,(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,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,它们将调用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控制器,禁止片选 */
+   //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,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++,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++,机器码为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,int size)
+{
+   unsigned int *pdwDest;
+   unsigned int *pdwSrc;
+   int i;
+  // printf("IN Copycode2ramn");
+   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,(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,143 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions,GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ *
+ * (C) Copyright 2002
+ * David Mueller,+ * 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,#1n"
+	  "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,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 %pn",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);
 
 	/*
@@ -2623,7 +2625,7 @@
 	/* Read manufacturer and device IDs */
 	*maf_id = chip->read_byte(mtd);
 	dev_id = chip->read_byte(mtd);
-
+	//printf("In %s,*maf_id is 0x%x,dev_id is 0x%x.n",__func__,*maf_id,dev_id);
 	/* Try again to make sure,as some systems the bus-hold or other
 	 * interface concerns can cause random data which looks like a
 	 * possibly credible NAND flash to appear. If the two results do
@@ -2638,7 +2640,7 @@
 	tmp_id = chip->read_byte(mtd);
 
 	if (tmp_manf != *maf_id || tmp_id != dev_id) {
-		printk(KERN_INFO "%s: second ID read did not match "
+		printk("%s: second ID read did not match "
 		       "%02x,%02x against %02x,%02xn",dev_id,tmp_manf,tmp_id);
 		return ERR_PTR(-ENODEV);
diff -urNwB u-boot-2010.06/include/configs/tq2440.h uboot-2010.06/include/configs/tq2440.h
--- u-boot-2010.06/include/configs/tq2440.h	1970-01-01 08:00:00.000000000 +0800
+++ uboot-2010.06/include/configs/tq2440.h	2012-05-09 21:15:42.181475572 +0800
@@ -0,217 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions,GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Gary Jennejohn <garyj@denx.de>
+ * David Mueller <d.mueller@elsoft.ch>
+ *
+ * Configuation settings for the SAMSUNG SMDK2410 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,+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#define CONFIG_DISPLAY_CPUINFO
+
+#define CONFIG_CMD_NAND
+#define CONFIG_CMDLINE_EDITING
+
+#ifdef CONFIG_CMDLINE_EDITING
+#undef CONFIG_AUTO_COMPLETE
+#else
+#define CONFIG_AUTO_COMPLETE
+#endif
+
+/* for tag(s) to transfer message to kernel */
+#define CONFIG_SETUP_MEMORY_TAGS 1
+#define CONFIG_CMDLINE_TAG 1
+#define CONFIG_INITRD_TAG 1
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_ARM920T	1	/* This is an ARM920T Core	*/
+#define CONFIG_S3C24X0	1	/* in a SAMSUNG S3C24x0-type SoC	*/
+#define CONFIG_S3C2410	1	/* specifically a SAMSUNG S3C2410 SoC	*/
+#define CONFIG_S3C2440	1	/* specifically a SAMSUNG S3C2410 SoC	*/
+#define CONFIG_SMDK2410	1	/* on a SAMSUNG SMDK2410 Board  */
+
+/* input clock of PLL */
+#define CONFIG_SYS_CLK_FREQ	12000000/* the SMDK2410 has 12MHz input clock */
+
+
+#define USE_920T_MMU		1
+#undef CONFIG_USE_IRQ			/* we don't need IRQ/FIQ stuff */
+
+/*
+ * Size of malloc() pool
+ */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 128*1024)
+#define CONFIG_SYS_GBL_DATA_SIZE	128	/* size in bytes reserved for initial data */
+
+/*
+ * Hardware drivers
+ */
+#define CONFIG_NET_MULTI
+//#define CONFIG_CS8900		/* we have a CS8900 on-board */
+//#define CONFIG_CS8900_BASE	0x19000300
+//#define CONFIG_CS8900_BUS16	/* the Linux driver does accesses as shorts */
+#define CONFIG_DRIVER_DM9000 1
+#define CONFIG_DM9000_BASE 0x20000000
+#define DM9000_IO CONFIG_DM9000_BASE
+#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
+#define CONFIG_DM9000_USE_16BIT
+
+
+/*
+ * select serial console configuration
+ */
+#define CONFIG_S3C24X0_SERIAL
+#define CONFIG_SERIAL1          1	/* we use SERIAL 1 on SMDK2410 */
+
+/************************************************************
+ * RTC
+ ************************************************************/
+#define	CONFIG_RTC_S3C24X0	1
+
+/* allow to overwrite serial and ethaddr */
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BAUDRATE		115200
+
+
+/*
+ * BOOTP options
+ */
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+
+
+/*
+ * Command line configuration.
+ */
+#include <config_cmd_default.h>
+
+#define CONFIG_CMD_CACHE
+#define CONFIG_CMD_DATE
+#define CONFIG_CMD_ELF
+#define CONFIG_CMD_PING
+
+
+#define CONFIG_BOOTDELAY	3
+/*#define CONFIG_BOOTARGS	"root=ramfs devfs=mount console=ttySA0,9600" */
+#define CONFIG_BOOTARGS "noinitrd root=/dev/mtdblock2 init=/linuxrc console=ttySAC0"
+/*#define CONFIG_ETHADDR	08:00:3e:26:0a:5b */
+#define CONFIG_ETHADDR		10:23:45:67:89:AB
+#define CONFIG_NETMASK          255.255.255.0
+#define CONFIG_IPADDR		192.168.10.66
+#define CONFIG_SERVERIP		192.168.10.96
+/*#define CONFIG_BOOTFILE	"elinos-lart" */
+/*#define CONFIG_BOOTCOMMAND	"tftp; bootm" */
+#define CONFIG_BOOTCOMMAND "nand read 0x32000000 0x200000 0x300000; bootm 0x32000000"
+
+#if defined(CONFIG_CMD_KGDB)
+#define CONFIG_KGDB_BAUDRATE	115200		/* speed to run kgdb serial port */
+/* what's this ? it's not used anywhere */
+#define CONFIG_KGDB_SER_INDEX	1		/* which serial port to use */
+#endif
+
+/*
+ * Miscellaneous configurable options
+ */
+#define	CONFIG_SYS_LONGHELP				/* undef to save memory		*/
+#define	CONFIG_SYS_PROMPT		"TQ2440 # "	/* Monitor Command Prompt	*/
+#define	CONFIG_SYS_CBSIZE		256		/* Console I/O Buffer Size	*/
+#define	CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE+sizeof(CONFIG_SYS_PROMPT)+16) /* Print Buffer Size */
+#define	CONFIG_SYS_MAXARGS		16		/* max number of command args	*/
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE	/* Boot Argument Buffer Size	*/
+
+#define CONFIG_SYS_MEMTEST_START	0x30000000	/* memtest works on	*/
+#define CONFIG_SYS_MEMTEST_END		0x33F00000	/* 63 MB in DRAM	*/
+
+#define	CONFIG_SYS_LOAD_ADDR		0x33000000	/* default load address	*/
+
+#define	CONFIG_SYS_HZ			1000
+
+/* valid baudrates */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600,19200,38400,57600,115200 }
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE	(128*1024)	/* regular stack */
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ	(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ	(4*1024)	/* FIQ stack */
+#endif
+
+/*-----------------------------------------------------------------------
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS	1	   /* we have 1 bank of DRAM */
+#define PHYS_SDRAM_1		0x30000000 /* SDRAM Bank #1 */
+#define PHYS_SDRAM_1_SIZE	0x04000000 /* 64 MB */
+
+#define PHYS_FLASH_1		0x00000000 /* Flash Bank #1 */
+
+#define CONFIG_SYS_FLASH_BASE		PHYS_FLASH_1
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+
+#if 0
+#define CONFIG_AMD_LV400	1	/* uncomment this if you have a LV400 flash */
+#endif
+#define CONFIG_AMD_LV800	1	/* uncomment this if you have a LV800 flash */
+
+#define CONFIG_SYS_MAX_FLASH_BANKS	1	/* max number of memory banks */
+#ifdef CONFIG_AMD_LV800
+#define PHYS_FLASH_SIZE		0x00200000 /* 2MB */
+#define CONFIG_SYS_MAX_FLASH_SECT	(19)	/* max number of sectors on one chip */
+#define CONFIG_ENV_ADDR		(CONFIG_SYS_FLASH_BASE + 0x1F0000) /* addr of environment */
+#endif
+#ifdef CONFIG_AMD_LV400
+#define PHYS_FLASH_SIZE		0x00080000 /* 512KB */
+#define CONFIG_SYS_MAX_FLASH_SECT	(11)	/* max number of sectors on one chip */
+#define CONFIG_ENV_ADDR		(CONFIG_SYS_FLASH_BASE + 0x070000) /* addr of environment */
+#endif
+
+/* timeout values are in ticks */
+#define CONFIG_SYS_FLASH_ERASE_TOUT	(5*CONFIG_SYS_HZ) /* Timeout for Flash Erase */
+#define CONFIG_SYS_FLASH_WRITE_TOUT	(5*CONFIG_SYS_HZ) /* Timeout for Flash Write */
+
+//#define	CONFIG_ENV_IS_IN_FLASH	1
+#define	CONFIG_ENV_IS_IN_NAND	1
+#define CONFIG_ENV_SIZE		0x40000	/* Total Size of Environment Sector */
+#define CONFIG_ENV_OFFSET 0x40000
+
+#define CONFIG_SYS_NAND_BASE 0x4E000000
+#define CONFIG_SYS_MAX_NAND_DEVICE  1
+#define NAND_MAX_CHIPS 1
+
+
+#endif	/* __CONFIG_H */
diff -urNwB u-boot-2010.06/Makefile uboot-2010.06/Makefile
--- u-boot-2010.06/Makefile	2010-06-30 05:28:28.000000000 +0800
+++ uboot-2010.06/Makefile	2012-05-09 21:14:35.443175990 +0800
@@ -156,7 +156,7 @@
 
 # set default to nothing for native builds
 ifeq ($(HOSTARCH),$(ARCH))
-CROSS_COMPILE ?=
+CROSS_COMPILE ?=arm-linux-
 endif
 
 # load other configuration
@@ -283,7 +283,8 @@
 endif
 
 __OBJS := $(subst $(obj),$(OBJS))
-__LIBS := $(subst $(obj),$(LIBS)) $(subst $(obj),$(LIBBOARD))
+#__LIBS := $(subst $(obj),$(LIBBOARD))
+__LIBS := $(subst $(obj),$(LIBBOARD)) $(subst $(obj),$(LIBS))
 
 #########################################################################
 #########################################################################
@@ -3051,6 +3052,9 @@
 smdk2410_config	:	unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm920t smdk2410 samsung s3c24x0
 
+tq2440_config	:	unconfig
+	@$(MKCONFIG) $(@:_config=) arm arm920t tq2440 samsung s3c24x0
+
 spear300_config 
 spear310_config 
 spear320_config :	unconfig

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读