微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > TE2410移植linux-2.6.14及调试过程总结(1)

TE2410移植linux-2.6.14及调试过程总结(1)

时间:11-10 来源:互联网 点击:

打印出来的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

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top