复制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启动。