我用的是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重新编辑 ]