您的位置 首页 主动

S3C2440 Linux驱动移植——NAND驱动

1修改分区表打开文件archarmplat-s3c24xxcommon-smdkc,修改mtd_partition结构体数组。修改后如下:[cpp]viewplaincopystaticstru

1. 修正分区表

翻开文件arch/arm/plat-s3c24xx/common-smdk.c,修正mtd_partition结构体数组。

修正后如下:

[cpp]view plaincopy

  1. staticstructmtd_partitionsmdk_default_nand_part[]={
  2. [0]={
  3. .name=“Uboot”,
  4. .size=0x00040000,
  5. .offset=0x00000000,
  6. },
  7. [1]={
  8. .name=“Kernel”,
  9. .offset=0x00200000,
  10. .size=0x00300000,
  11. },
  12. [2]={
  13. .name=“filesystem”,
  14. .offset=0x00500000,
  15. .size=MTDPART_SIZ_FULL,
  16. }
[cpp]view plaincopy

  1. };

TQ2440板上的NAND为256M,请依据你的NAND实践巨细分配空间。

2. 修正NAND控制器参数

翻开文件arch/arm/plat-s3c24xx/common-smdk.c,修正smdk_nand_info结构体。

修正后如下:

[cpp]view plaincopy

  1. staticstructs3c2410_platform_nandsmdk_nand_info={
  2. .tacls=0,//10,//20,
  3. .twrph0=21,//25,//60,
  4. .twrph1=5,//10,//20,
  5. .nr_sets=ARRAY_SIZE(smdk_nand_sets),
  6. .sets=smdk_nand_sets,
  7. };

这儿的三个参数tacls,twrph0,和twrph1是怎么给出的? 咱们来剖析下。

先看下这个结构体的界说,坐落arch/arm/mach-s3c2410/include/mach/nand.h:

[cpp]view plaincopy

  1. structs3c2410_platform_nand{
  2. inttacls;
  3. inttwrph0;
  4. inttwrph1;
  5. unsignedintignore_unset_ecc:1;
  6. intnr_sets;
  7. structs3c2410_nand_set*sets;
  8. void(*select_chip)(structs3c2410_nand_set*,
  9. intchip);
  10. };

看到了对这三个参数的阐明,这儿提到了这三个参数的单位为纳秒,请注意。

那么这三个参数究竟从哪来的呢? 它来自于S3C2440 nand 控制器的NFCONF控制器,如下:

已然找到这三个参数的出处了,那么它们究竟是何含义呢?咱们里看下:

这幅时序图相同来自S3C2440的datasheet。

经过这幅图和struct s3c2410_platform_nand中的注释,咱们能够对这3个参数做出如下界说。

TACLS:标明在CLE/ALE拉高后,多少时刻今后才答应将nWE拉低。

TWRPH0:标明nWE低电平继续的时刻。

TWRPH1:标明nWE变为高电平后,多少时刻后答应CLE/ALE拉低。

知道参数的含义后,咱们来看下NAND芯片K9F1208U0C的datasheet来确认这3个参数的值。

从这个时序图,咱们能够直观地看到twp对应着参数twrph0,而tclh关于着参数twrph1。

可是tacls怎么得出呢?从图中并不能直接得出该参数的值,需求转个弯,那便是将tcls减去twp,就能够得到tacls了。

综上所述,为了得到nand控制器所需的3个参数,咱们需求获得该nand芯片的3个时序参数:twp,tcls和tclh。

经过查找该nand的datasheet,3个时序参数的值如下:

twp=21, tcls=21, tclh=5。

将这3个时序参数转为咱们需求的3个参数,单位为纳秒(ns):

tacls = tcls-twp = 21 – 21 = 0 ns

twrph0= twp = 21 ns

twrph1 = tclh = 5 ns

至此,就成功计算出三个参数的值了

3. 装备内核

4. 验证

在经过上述过程后,编译内核并将内核少入nand,发动体系。在Linux的发动信息中,会有如下输出:

……

S3C24XX NAND Driver, (c) 2004 Simtec Electronics
s3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns
s3c24xx-nand s3c2440-nand: NAND hardware ECC
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
Scanning device for bad blocks
Bad eraseblock 781 at 0x0000061a0000
Bad eraseblock 1113 at 0x000008b20000
Bad eraseblock 1117 at 0x000008ba0000
Bad eraseblock 1481 at 0x00000b920000
Bad eraseblock 1566 at 0x00000c3c0000
Bad eraseblock 1885 at 0x00000eba0000
Creating 3 MTD partitions on “NAND 256MiB 3,3V 8-bit”:
0x000000000000-0x000000040000 : “Uboot”
0x000000200000-0x000000500000 : “Kernel”
0x000000500000-0x000010000000 : “filesystem”

……

上述信息标明以成功访问了NAND FLASH。

这儿,对第二行的输出进行个阐明。

UBOOT发动将S3C2440的作业频率 FCLK:HCLK:PCLK = 8:4 :1,

而FCLK为400Mhz,那么HCLK为100Mhz,依据NFCONF寄存器的阐明,寄存器中的这3个参数都跟HCLK有关,有必要为1/HCLK的倍数,

也便是1/100MHz=10ns的倍数。

经过上面第二行的输出信息,Twrph0为 30ns而Twrph1为10ns,这是显而定见的。

因为参数有必要为10ns的倍数,并且有必要大于datasheet给出的值,因而向上取到10的倍数,也即5ns取到10ns,21ns取到30ns。

那么为什么Tacls是10ns呢?分明给出的是0ns,是不是驱动不答应参数为0ns?

在S3C2440的nand驱动中,参数的值是经过如下函数确认的:

[cpp]view plaincopy

  1. staticints3c_nand_calc_rate(intwanted,unsignedlongclk,intmax)
  2. {
  3. intresult;
  4. result=DIV_ROUND_UP((wanted*clk),NS_IN_KHZ);
  5. pr_debug(“result%dfrom%ld,%d\n”,result,clk,wanted);
  6. if(result>max){
  7. printk(“%dnsistoobigforcurrentclockrate%ld\n”,wanted,clk);
  8. return-1;
  9. }
  10. if(result<1)
  11. result=1;
  12. returnresult;
  13. }

参数wanted便是0(ns),而clk即为HCLK/1000。

DIV_ROUND_UP宏将回来0,可是if对result进行了约束,也便是不答应小于0,因而将参数值设置为1,并回来给调用函数。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/zhudong/263154.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部