复制S3C2410_nand.c为S3C2440_nand.c,修改drivers/mtd/nand/makefile编译S3C2440_nand.c而不编译S3C2410_nand.c
添加:COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
smdk2440.h中:
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
改为:
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC
s3c2440_nand.c:
S3C2440_hwcontrol()中修改使能选中和取消选中
board_nand_init()中:
把 :nand->select_chip = NULL;
改为:nand->select_chip = s3c2440_nand_select;
编译烧写启动,即可识别nand,支持nand启动。
添加:COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o
smdk2440.h中:
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
改为:
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC
s3c2440_nand.c:
S3C2440_hwcontrol()中修改使能选中和取消选中
board_nand_init()函数中初始化:修改为
tacls = 0; twrph0 = 1; twrph1 = 0; cfg = ((tacls-1)<<12)|((twrph0-1)<<8)|((twrp1-1)<<4); writel((1<<4)|(1<<1)|(1<<0),&nand_reg->nfcont);修改:s3c2440_hwcontrol()和nand_select_chip()
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(); debug("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_NCLE; //if (!(ctrl & NAND_ALE)) // IO_ADDR_W |= S3C2440_ADDR_NALE; //if (cmd != NAND_CMD_NONE) // writeb(cmd, chip->IO_ADDR_W); /*前面我们指定的 chip->IO_ADDR_W = (void *)&nand_reg->nfdata; 显然将命令发送到数据寄存器 是错误,我们看到在发送之前 chip->IO_ADDR_W = (void *)IO_ADDR_W; IO_ADDR_W 这个变量是根据 ctrl 来计算的,它有以下取值 ctrl :!NAND_CLE , S3C2410_ADDR_NCLE == 8 ->地址 ctrl :!NAND_ALE , S3C2410_ADDR_NALE == 4 -> 指令 ctrl : (!NAND_CLE) | (!NAND_ALE) -> 8 | 4 == 12 -> 数据 */ //修改IO_ADDR_W后再写 if (!(ctrl & NAND_CLE)) IO_ADDR_W |= 12; if (!(ctrl & NAND_ALE)) IO_ADDR_W |= 8; if ((!(ctrl & NAND_CLE)) && (!(ctrl & NAND_ALE))) IO_ADDR_W = IO_ADDR_W + 4; //8|12 == 12 != 16 因此 + 4 chip->IO_ADDR_W = (void *)IO_ADDR_W; //chip->IO_ADDR_W = (void *)IO_ADDR_W; /* if (ctrl & NAND_NCE) //使能选中 writel(readl(&nand->nfconf) & ~S3C2440_NFCONF_nFCE, &nand->nfconf); else //取消选中 writel(readl(&nand->nfconf) | S3C2440_NFCONF_nFCE, &nand->nfconf); */ if (ctrl & NAND_NCE) writel(readl(&nand->nfcont) & ~(1<<1), &nand->nfcont); else writel(readl(&nand->nfcont) | (1<<1), &nand->nfcont); } if (cmd != NAND_CMD_NONE) writeb(cmd, chip->IO_ADDR_W); }nand_base.c默认的选中芯片函数中没有代码实现选中芯片:
static void nand_select_chip(struct mtd_info *mtd, int chipnr) { struct nand_chip *chip = mtd->priv; switch (chipnr) { case -1: chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE); break; case 0: break; default: BUG(); } }自定义芯片选中函数:
static void s3c2440_nand_select(struct mtd_info *mtd, int chipnr) { struct s3c2440_nand *nand = s3c2440_get_base_nand(); switch (chipnr) { case -1: nand->nfcont |= (1<<1); break; case 0: nand->nfcont &= ~(1<<1); break; default: BUG(); } }并把这个函数填充到nand->select_chip:
board_nand_init()中:
把 :nand->select_chip = NULL;
改为:nand->select_chip = s3c2440_nand_select;
编译烧写启动,即可识别nand,支持nand启动。