微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S5PV210(TQ210)学习笔记——Nand flash驱动编写

S5PV210(TQ210)学习笔记——Nand flash驱动编写

时间:11-28 来源:互联网 点击:
跟裸机程序一样,S5PV210Nand flash模块跟S3C2440的Nand flash模块非常相似,如果不引入ECC,驱动程序的编写也非常简单,具体的分析及编写过程强烈推荐观看韦东山老师的视频教程,我是使用的Linux-3.8.6(Linux-3.8.3也一样)内核,驱动的API函数有些变化,不过原理是相通的,稍微看一下内核源码并参考下其他平台的相关代码就可以自己写出Nand flash驱动了,下面是Nand flash驱动的源码,没有启用ECC,当然,你也可以改成软件ECC,但是我的觉得既然软件ECC不如HWECC快,我就采用硬件ECC吧,我会在下篇文章中加入HWECC。

  1. #include
  2. #include
  3. #include
  4. #include
  5. #include
  6. #include
  7. #include
  8. #include
  9. structs5p_nand_regs{
  10. unsignedlongnfconf;
  11. unsignedlongnfcont;
  12. unsignedlongnfcmmd;
  13. unsignedlongnfaddr;
  14. unsignedlongnfdata;
  15. unsignedlongnfmeccd0;
  16. unsignedlongnfmeccd1;
  17. unsignedlongnfseccd;
  18. unsignedlongnfsblk;
  19. unsignedlongnfeblk;
  20. unsignedlongnfstat;
  21. unsignedlongnfeccerr0;
  22. unsignedlongnfeccerr1;
  23. unsignedlongnfmecc0;
  24. unsignedlongnfmecc1;
  25. unsignedlongnfsecc;
  26. unsignedlongnfmlcbitpt;
  27. };
  28. structs5p_nand_ecc{
  29. unsignedlongnfeccconf;
  30. unsignedlongnfecccont;
  31. unsignedlongnfeccstat;
  32. unsignedlongnfeccsecstat;
  33. unsignedlongnfeccprgecc0;
  34. unsignedlongnfeccprgecc1;
  35. unsignedlongnfeccprgecc2;
  36. unsignedlongnfeccprgecc3;
  37. unsignedlongnfeccprgecc4;
  38. unsignedlongnfeccprgecc5;
  39. unsignedlongnfeccprgecc6;
  40. unsignedlongnfeccerl0;
  41. unsignedlongnfeccerl1;
  42. unsignedlongnfeccerl2;
  43. unsignedlongnfeccerl3;
  44. unsignedlongnfeccerl4;
  45. unsignedlongnfeccerl5;
  46. unsignedlongnfeccerl6;
  47. unsignedlongnfeccerl7;
  48. unsignedlongnfeccerp0;
  49. unsignedlongnfeccerp1;
  50. unsignedlongnfeccerp2;
  51. unsignedlongnfeccerp3;
  52. unsignedlongnfeccconecc0;
  53. unsignedlongnfeccconecc1;
  54. unsignedlongnfeccconecc2;
  55. unsignedlongnfeccconecc3;
  56. unsignedlongnfeccconecc4;
  57. unsignedlongnfeccconecc5;
  58. unsignedlongnfeccconecc6;
  59. };
  60. staticstructnand_chip*nand_chip;
  61. staticstructmtd_info*s5p_mtd_info;
  62. staticstructs5p_nand_regs*s5p_nand_regs;
  63. staticstructs5p_nand_ecc*s5p_nand_ecc;
  64. staticstructclk*s5p_nand_clk;
  65. staticstructmtd_partitions5p_nand_partions[]={
  66. [0]={
  67. .name="bootloader",
  68. .offset=0,
  69. .size=SZ_1M,
  70. },
  71. [1]={
  72. .name="kernel",
  73. .offset=MTDPART_OFS_APPEND,
  74. .size=5*SZ_1M,
  75. },
  76. [2]={
  77. .name="rootfs",
  78. .offset=MTDPART_OFS_APPEND,
  79. .size=MTDPART_SIZ_FULL,
  80. },
  81. };
  82. staticvoids5p_nand_select_chip(structmtd_info*mtd,intchipnr){
  83. if(chipnr==-1){
  84. s5p_nand_regs->nfcont|=(1<1);
  85. }
  86. else{
  87. s5p_nand_regs->nfcont&=~(1<1);
  88. }
  89. }
  90. staticvoids5p_nand_cmd_ctrl(structmtd_info*mtd,intcmd,unsignedintctrl)
  91. {
  92. if(ctrl&NAND_CLE){
  93. s5p_nand_regs->nfcmmd=cmd;
  94. }
  95. else{
  96. s5p_nand_regs->nfaddr=cmd;
  97. }
  98. }
  99. staticints5p_nand_ready(structmtd_info*mtd){
  100. return(s5p_nand_regs->nfstat&0x1);
  101. }
  102. staticints5p_nand_probe(structplatform_device*pdev){
  103. intret=0;
  104. structresource*mem;
  105. //硬件部分初始化
  106. mem=platform_get_resource(pdev,IORESOURCE_MEM,0);
  107. if(!mem){
  108. dev_err(&pdev->dev,"cantgetI/Oresourcemem");
  109. return-ENXIO;
  110. }
  111. s5p_nand_regs=(structs5p_nand_regs*)ioremap(mem->start,resource_size(mem));
  112. if(s5p_nand_regs==NULL){
  113. dev_err(&pdev->dev,"ioremapfailed");
  114. ret=-EIO;
  115. gotoerr_exit;
  116. }
  117. s5p_nand_ecc=(structs5p_nand_ecc*)ioremap(0xB0E20000,sizeof(structs5p_nand_ecc));
  118. if(s5p_nand_ecc==NULL){
  119. dev_err(&pdev->dev,"ioremapfailed");
  120. ret=-EIO;
  121. gotoerr_iounmap;
  122. }
  123. s5p_nand_clk=clk_get(&pdev->dev,"nand");
  124. if(s5p_nand_clk==NULL){
  125. dev_dbg(&pdev->dev,"getclkfailed");
  126. ret=-ENODEV;
  127. gotoerr_iounmap;
  128. }
  129. clk_enable(s5p_nand_clk);
  130. s5p_nand_regs->nfconf=(3<12)|(5<8)|(3<4)|(1<1);
  131. s5p_nand_regs->nfcont|=3;
  132. //分配驱动相关结构体
  133. nand_chip=(structnand_chip*)kzalloc(sizeof(structnand_chip),GFP_KERNEL);
  134. if(nand_chip==NULL){
  135. dev_err(&pdev->dev,"failedtoallocatenand_chipstructure");
  136. ret=-ENOMEM;
  137. gotoerr_clk_put;
  138. }
  139. s5p_mtd_info=(structmtd_info*)kzalloc(sizeof(structmtd_info),GFP_KERNEL);
  140. if(s5p_mtd_info==NULL){
  141. dev_err(&pdev->dev,"failedtoallocatemtd_infostructure");
  142. ret=-ENOMEM;
  143. gotoerr_free_chip;
  144. }
  145. //设置驱动相关结构体
  146. nand_chip->select_chip=s5p_nand_select_chip;
  147. nand_chip->nand_c

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

网站地图

Top