您的位置:首页 > 其它

uboot.2015.07移植之驱动NAND Flash(7)

2016-07-05 16:28 363 查看

移植u-boot-2015.07之修改程序支持检测nand flash

1.程序执行顺序

board_init_r
nand_init
nand_init_chip
board_nand_init
nand_scan
nand_scan_ident
nand_set_defaults
nand_get_flash_type
nand_register   //注册 NAND Flash , 也就是添加 mtd_info 结构体,里面描述了大小,擦除块等等


(注意:在此版本的uboot里面获取 nand flash 控制器结构体起始地址不再是 s3c2440_get_base_nand(), 而是 s3c24x0_get_base_nand())

2.需要的驱动函数

回想一下之前裸板驱动 NAND Flash 程序的时候是怎样做的

设置 NAND Flash 控制器的时间参数以及是否使能 NAND Flash 控制器

首先取消 NAND Flash 的片选

NAND Flash 的片选使能/禁止函数,读写函数,以及等待函数

根据板子来判断哪一些函数是通用的,而哪一些函数可能会跟不同的芯片而变化

在 NAND Flash 的驱动函数里面挨个查找这些函数是否符合自己的使用要求,如果不满足,就要进行修改,如果满足,那就保留。

3.改写驱动函数

拷贝 drivers/mtd/nand 里面的 s3c2410_nand.c 为 s3c2440_nand.c, 修改该目录的 Makefile ,在
COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o
下面添加
COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o


修改 smdk2440.h 里面的

决定编译哪个C文件

#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC




#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC


修改 s3c2440_nand.c 里面的 board_nand_init 函数中的

时间参数的设置

tacls = 4;
twrph0 = 8;
twrph1 = 8;




tacls  = 2; //时间参数,参照 nand flash 的芯片手册
twrph0 = 3;
twrph1 = 2;


时间参数对应在寄存器里的位置

#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)
#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)
#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)


改为

#define S3C2440_NFCONF_TACLS(x)    ((x)<<12)
#define S3C2440_NFCONF_TWRPH0(x)   ((x)<<8)
#define S3C2440_NFCONF_TWRPH1(x)   ((x)<<4)


合并时间参数,等待写入寄存器

cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);


改为

cfg = S3C2440_NFCONF_TACLS(tacls - 1);
cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
/* 修改里面的 2410 字样为 2440 ,比如 s3c2410_hwcontrol 与 s3c2410_dev_ready
下面需要再添加一个使能 NAND Flash 控制器的语句 */
cfg = 1 << 0;
writel(cfg, &nand->nfcont);


添加 s3c2440_nand_select_chip 函数,传给 nand 结构体,nand->select_chip = s3c2440_nand_select_chip;

static void s3c2440_nand_select_chip(struct mtd_info *mtd, int chipnr)
{
struct s3c2440_nand *nand = s3c24x0_get_base_nand();

switch (chipnr) {
case -1:    //取消选中
writel(readl(&nand->nfcont) | (1 << 1), &nand->nfcont);
break;
case 0: //选中
writel(readl(&nand->nfcont) & ~(1 << 1), &nand->nfcont);
break;

default:
BUG();
}
}


修改 s3c2440_hwcontrol 函数

static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
struct s3c2410_nand *nand = s3c24x0_get_base_nand();

debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);

if(ctrl & NAND_CLE)
{
writeb(cmd, (&nand->nfcmd));
}
else if(ctrl & NAND_ALE)
{
writel(cmd, (&nand->nfaddr));
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: