TE2410移植linux-2.6.14及调试过程总结(1)
打印出来的id值确实不正确,首先我的NAND Flash肯定正常工作,在u-boot中一直是好的,那么可能是Linux中对Flash读写的出问题了,怀疑是发出命令后的延时有问题,向NAND Flash发出读取id命令后的延时太短,导致读出来的值错误,nand_wait_ready这个就是延时等待命令执行完成的函数,经过测试没有问题,到这个时候,真有点崩溃了.然后估计是NAND Flash的NFCONF寄存器设置有问题, NFCONF寄存器在函数s3c2410_nand_inithw中初始化,s3c2410_nand_inithw中将NFCONF寄存器的值打印出来,如下:
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing:Tacls10ns, Twrph010ns, Twrph110ns
s3c2410-nand: NF_CONF is0x8000
与u-boot中设置的NFCONF寄存器值比较发现,不同的是TACLS TWRPH0 TWRPH1以及是否初始化ECC,nFCE的值
U-boot中TACLS TWRPH0 TWRPH1值分别为0 4 2,初始化ECC, nFCE=1(inactive)
Linux中TACLS TWRPH0 TWRPH1值分别为0 0 0,未初始化ECC, nFCE=0(active)
应该是TACLS TWRPH0 TWRPH1的问题,查看S3C2410 user manual和NAND Flash用户手册Samsung K9F1208U0M user manual,找到三张图,如下:
图1 s3c2410 user manual, nand flash memory timing
显然s3c2410 user manual推荐值是TACLS=0 TWRPH0=1 TWRPH1=0
TACLS:1个HCLK TWRPH0:2个HCLK TWRPH1:1个HCLK
内核的频率为200MHZ,即FCLK=200MHZ,则HCLK=100MHZ(周期为10ns),所以
TACLS:10ns TWRPH0:20ns TWRPH1:10ns
图2 NAND Flash(K9F1208U0M) user manual,Read and Write timing
tCLS等价于图1中的TACLS;tWP等价于图1中的TWRPH0;tCLH等价于图1中的TWRPH1
图3 NAND Flash(K9F1208U0M) user manual
结合前3张图,可以看出对NAND Flash(K9F1208U0M)进行读写的顺序要求为:
TACLS <----------->tCLS,最小值为0ns
TWRPH0<----------->tWP,最小值为25ns
TWRPH1<----------->tCLH,最小值为10ns
内核的频率为200MHZ,即FCLK=200MHZ,则HCLK=100MHZ(周期为10ns)
TACLS=0,TWRPH0=2,TWRPH1=0即可满足时序要求,此时
TACLS:10nsTWRPH0:30nsTWRPH1:10ns
现在再看看先前串口输出的信息:
s3c2410-nand: mapped registers at c4980000
s3c2410-nand: timing:Tacls 10ns, Twrph0 10ns, Twrph1 10ns
No NAND device found!!!
很显然Twrph0 10ns <25ns,原来如此!!!!
不过我试了一下TACLS=0,TWRPH0=1,TWRPH1=0, TACLS:10nsTWRPH0:20nsTWRPH1:10ns,NAND Flash照样正常工作.不知道为什么.
现在要说明一下我是如何修改的, TACLSTWRPH0TWRPH1的值在linux-2.6.14\arch\arm\mach-s3c2410\devs.c中已经设置,代码如下:
struct s3c2410_platform_nandsuperlpplatform={
tacls:0,
twrph0:3,
twrph1:0,
sets:&nandset,
nr_sets:1,
};
这里设置的值和上面的分析是一致的,应该没有问题,但是为什么打印出来的却是
s3c2410-nand: timing:Tacls 10ns, Twrph0 10ns, Twrph1 10ns
s3c2410_nand_inithw函数对NFCONF寄存器初始化,代码如下:
static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
struct device *dev)
{
struct s3c2410_platform_nand *plat = to_nand_plat(dev);
unsigned int tacls, twrph0, twrph1;
unsigned long clkrate = clk_get_rate(info->clk);
unsigned long cfg;
/* calculate the timing information for the controller */
if (plat != NULL) {
tacls= s3c2410_nand_calc_rate(plat->tacls, clkrate, 4);
twrph0 = s3c2410_nand_calc_rate(plat->twrph0, clkrate, 8);
twrph1 = s3c2410_nand_calc_rate(plat->twrph1, clkrate, 8);
printk("plat->tacls:%d\n",plat->tacls);
printk("plat->twrph0:%d\n",plat->twrph0);
printk("plat->twrph1:%d\n",plat->twrph1);
printk("tacls:%d\n",tacls);
printk("twrph0:%d\n",twrph0);
printk("twrph1:%d\n",twrph1);
printk("clkrate:%d\n",clkrate);
tacls=1;
twrph0 =2;
twrph1 =1;
} else {
/* default timings */
tacls = 4;
twrph0 = 8;
twrph1 = 8;
}
if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
printk(KERN_ERR PFX "cannot get timings suitable for board\n");
return -EINVAL;
}
printk(KERN_INFO PFX "timing: Tacls %ldns, Twrph0 %ldns, Twrph1 %ldns\n",
to_ns(tacls, clkrate),
to_ns(twrph0, clkrate),
to_ns(twrph1, clkrate));
if (!info->is_s3c2440) {
cfg= S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls-1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0-1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1-1);
} else {
cfg= S3C2440_NFCONF_TACLS(tacls-1);
cfg|= S3C2440_NFCONF_TWRPH0(twrph0-1);
cfg|= S3C2440
TE2410移植linux-2 6 14调试过 相关文章:
- TE2410移植linux-2.6.14及调试过程总结(2)(11-10)
- 达芬奇数字媒体片上系统的架构和Linux启动过程(06-02)
- 基于TMS320DM642的农药喷洒系统(04-22)
- 用DSP56F805 PWM模块输出高频正弦波(05-25)
- 一种基于DSP平台的快速H.264编码算法的设计(05-19)
- 基于DSP的信号采集处理系统(07-21)