u-boot-1.3.4移植到s3c2440之nand驱动
http://blogold.chinaunix.net/u1/57747/showart_2258787.html
折腾了两个晚上,终于把s3c2440板子上的nand驱动搞定了,把需要注意的地方记下来,供大家参考。
这次使用的u-boot版本为1.3.4,现在还没有加上从nand启动的部分,现在使用从sdram启动的方式,修改好nand驱动后,现在环境变量可以存放到nand中,具体要修改的地方如下:
1、板子配置头文件
在板子的配置头文件中要加入如下代码:
| .......................................................
 #define CONFIG_CMD_NAND#define CFG_ENV_IS_IN_NAND  1
 #define CFG_ENV_SIZE        0x10000 /* Total Size of Environment Sector */
 #define CFG_ENV_OFFSET      0x30000
 
 #define CFG_MAX_NAND_DEVICE 1
 #define CFG_NAND_BASE 0x4E000000
 .......................................................... | 
2、修改cpu/arm920t/s3c24x0/nand.c文件
2.1、修改寄存器相关宏定义
把该文件的头部定义的一些宏做如下修改:
| #define __REGb(x)   (*(volatile unsigned char *)(x))#define __REGi(x)   (*(volatile unsigned int *)(x))
 
 #define NF_BASE     0x4e000000
 #define NFCONF      __REGi(NF_BASE + 0x0)
 #define NFCONT      __REGi(NF_BASE + 0x04)
 #define NFCMD       __REGb(NF_BASE + 0x08)
 #define NFADDR      __REGb(NF_BASE + 0x0C)
 #define NFDATA      __REGb(NF_BASE + 0x10)
 #define NFSTAT      __REGb(NF_BASE + 0x20)
 
 #define S3C2410_NFCONF_EN          (1<<1)
 #define S3C2410_NFCONF_512BYTE     (1<<14)
 #define S3C2410_NFCONF_4STEP       (1<<13)
 #define S3C2410_NFCONF_INITECC     (1<<12)
 #define S3C2410_NFCONF_nFCE        (1<<1)
 #define S3C2410_NFCONF_TACLS(x)    ((x)<<12)
 #define S3C2410_NFCONF_TWRPH0(x)   ((x)<<8)
 #define S3C2410_NFCONF_TWRPH1(x)   ((x)<<4)
 | 
修改完成后的代码如上。这里主要是由于2440与2410的nand控制器寄存器有一定的区别。
2.2、修改s3c2410_hwcontrol函数
s3c2410_hwcontrol函数修改后的代码如下:
| static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd){
 struct nand_chip *chip = mtd->priv;
 
 DEBUGN("hwcontrol(): 0x%02x: ", cmd);
 
 switch (cmd) {
 case NAND_CTL_SETNCE:
 NFCONT &= ~S3C2410_NFCONF_nFCE;
 DEBUGN("NFCONF=0x%08x\n", NFCONF);
 break;
 
 case NAND_CTL_CLRNCE:
 NFCONT |= S3C2410_NFCONF_nFCE;
 DEBUGN("NFCONF=0x%08x\n", NFCONF);
 break;
 
 case NAND_CTL_SETALE:
 chip->IO_ADDR_W = NF_BASE + 0xc;
 DEBUGN("SETALE\n");
 break;
 
 case NAND_CTL_SETCLE:
 chip->IO_ADDR_W = NF_BASE + 0x8;
 DEBUGN("SETCLE\n");
 break;
 
 default:
 chip->IO_ADDR_W = NF_BASE + 0x10;
 break;
 }
 return;
 }
 | 
这里做修改也是因为2410与2440的nand控制器寄存器定义存在差别。
2.3、修改board_nand_init函数
这个函数是初始化nand的时候调用,修改后的代码如下:
| int board_nand_init(struct nand_chip *nand){
 u_int32_t cfg;
 u_int8_t tacls, twrph0, twrph1;
 S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
 
 DEBUGN("board_nand_init()\n");
 
 clk_power->CLKCON |= (1 << 4);
 
 /* initialize hardware */
 twrph0 = 7; twrph1 = 7; tacls = 7;
 
 cfg |= S3C2410_NFCONF_TACLS(tacls);
 cfg |= S3C2410_NFCONF_TWRPH0(twrph0);
 cfg |= S3C2410_NFCONF_TWRPH1(twrph1);
 
 NFCONF = cfg;
 NFCONT = (1 << 4) | (1 << 0);
 NFSTAT = 6;
 
 /* initialize nand_chip data structure */
 nand->IO_ADDR_R = nand->IO_ADDR_W = 0x4e000010;
 
 /* read_buf and write_buf are default */
 /* read_byte and write_byte are default */
 
 /* hwcontrol always must be implemented */
 nand->hwcontrol = s3c2410_hwcontrol;
 
 nand->dev_ready = s3c2410_dev_ready;
 #ifdef CONFIG_S3C2410_NAND_HWECC
 nand->enable_hwecc = s3c2410_nand_enable_hwecc;
 nand->calculate_ecc = s3c2410_nand_calculate_ecc;
 nand->correct_data = s3c2410_nand_correct_data;
 nand->eccmode = NAND_ECC_HW3_512;
 #else
 nand->eccmode = NAND_ECC_SOFT;
 #endif
 
 #ifdef CONFIG_S3C2410_NAND_BBT
 nand->options = NAND_USE_FLASH_BBT;
 #else
 nand->options = 0;
 #endif
 
 DEBUGN("end of nand_init\n");
 
 return 0;
 }
 | 
到这里,nand.c文件就修改完成了。
3、修改include/s3c24x0.h文件
该文件中修改S3C2410_NAND结构体定义如下:
| typedef struct {S3C24X0_REG32   NFCONF;
 S3C24X0_REG32   NFCONT;
 S3C24X0_REG32   NFCMD;
 S3C24X0_REG32   NFADDR;
 S3C24X0_REG32   NFDATA;
 S3C24X0_REG32   NFMECC0;
 S3C24X0_REG32   NFMECC1;
 S3C24X0_REG32   NFSECC;
 S3C24X0_REG32   NFSTAT;
 S3C24X0_REG32   NFESTAT0;
 S3C24X0_REG32   NFESTAT1;
 S3C24X0_REG32   NFECC;
 } /*__attribute__((__packed__))*/ S3C2410_NAND;
 | 
到此为止,支持nand的代码就修改完成了。