主题 : Nand flash 驱动程序的疑问 复制链接 | 浏览器收藏 | 打印
级别: 骑士
UID: 11942
精华: 1
发帖: 144
金钱: 775 两
威望: 155 点
综合积分: 308 分
注册时间: 2009-12-25
最后登录: 2022-01-16
楼主  发表于: 2010-06-30 17:06

 Nand flash 驱动程序的疑问

我用的是2.6.32的核,对nand的驱动有好多疑问,请各位指点:

 nandflash采用platform方式驱动,首先看device方面:
nand的部分被定义到板级文件mach-mini2440.h中,其中有时需参数的设定:
static struct s3c2410_platform_nand friendly_arm_nand_info = { 
.tacls = 20, 
.twrph0 = 60, 
.twrph1 = 20,
.nr_sets = ARRAY_SIZE(friendly_arm_nand_sets),
.sets = friendly_arm_nand_sets, .ignore_unset_ecc = 1,
};
.tacls = 20,.twrph0 = 60,.twrph1 = 20,这三个参数的单位应该是ns吧,
可是从kernel启动信息发现:Tacls=3, 29ns Twrph0=7 69ns, Twrph1=3 29ns
应该是Tacls=2, 20ns Twrph0=6 60ns, Twrph1=2 20ns

这是为什么呢?
看一下platform的drvice部分:
在driver\mtd\nand\s3c2410.c中,s3c24xx_nand_probe->s3c2410_nand_inithw->s3c2410_nand_setrate中涉及到了时需参数的设定:
info->clk_rate = clkrate; 
clkrate /= 1000; /* turn clock into kHz for ease of use */
if (plat != NULL)
 {
   tacls = s3c_nand_calc_rate(plat->tacls, clkrate, tacls_max); 
  twrph0 = s3c_nand_calc_rate(plat->twrph0, clkrate, 8); 
  twrph1 = s3c_nand_calc_rate(plat->twrph1, clkrate, 8); 
} else {
其中clkrate是nand的时钟,应该是HCLK=100MH,除以1000后变成100000。
下面是s3c_nand_calc_rate:
#define NS_IN_KHZ 1000000
static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)
{      
  int result;
  result = (wanted * clk) / NS_IN_KHZ;  
  result++;    
   ……   
  return result;
}
经过计算tacls=20*100000/1000000+1=2+1=3, twrph0=7,twrph1=3。这样就与kernel的启动信息匹配上了。
但为啥是29ns,69ns,29ns,而不是30,70,30这是我的第一个疑问?

接着往下看,在s3c2410_nand_setrate中对nand寄存器进行赋值操作:
set |= S3C2410_NFCONF_TACLS(tacls - 1); 
set |= S3C2410_NFCONF_TWRPH0(twrph0 - 1); 
set |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);
将tacls-1赋值,这很好理解,nand datasheet上有说,可是这与在device中设定的20 60 20完全不符。这是为什么呢?这是我的第二个疑问。
第三,为什么内核要在s3c_nand_calc_rate中加入result++呢?如果没有它,岂不是更直观?
[ 此帖被cole3在2010-06-30 17:17重新编辑 ]