FL2440开发板的U-boot-2010.09版本移植(六)uboot架构中NAND Flash驱动修改

时间:2021-02-17 17:13:06

       uboot代码中的NAND Flash的读写驱动中存在一些错误,需要进行修改后才能完成,主要修改drivers/mtd/nand/s3c2410_nand.c文件,首先修改27行如下:

[cpp]  view plain copy
  1. #define NF_BASE         0x4e000000  
  2.   
  3. #if defined(CONFIG_S3C2410)  
  4. #define S3C2410_NFCONF_EN          (1<<15)  
  5. #define S3C2410_NFCONF_512BYTE     (1<<14)  
  6. #define S3C2410_NFCONF_4STEP       (1<<13)  
  7. #define S3C2410_NFCONF_INITECC     (1<<12)  
  8. #define S3C2410_NFCONF_nFCE        (1<<11)  
  9. #define S3C2410_NFCONF_TACLS(x)    ((x)<<8)  
  10. #define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)  
  11. #define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)  
  12.   
  13. #define S3C2410_ADDR_NALE 4  
  14. #define S3C2410_ADDR_NCLE 8  
  15. #endif  
  16.   
  17. #if defined(CONFIG_S3C2440)  
  18. #define S3C2410_NFCONT_EN          (1<<0)  
  19. #define S3C2410_NFCONT_INITECC     (1<<4)  
  20. #define S3C2410_NFCONT_nFCE        (1<<1)  
  21. #define S3C2410_NFCONT_MAINECCLOCK (1<<5)  
  22. #define S3C2410_NFCONF_TACLS(x)    ((x)<<12)  
  23. #define S3C2410_NFCONF_TWRPH0(x)   ((x)<<8)  
  24. #define S3C2410_NFCONF_TWRPH1(x)   ((x)<<4)  
  25.    
  26. #define S3C2410_ADDR_NALE 0x08  
  27. #define S3C2410_ADDR_NCLE 0x0c  
  28. #endif  

u-boot.2010.09自带的S3C2410_nand.c的s3c2410_hwcontrol函数有错。在此函数中,把chip->IO_ADDR_W值改写了,导致在写数据时出现错误。解决方法是使用一全局变量代替 chip->IO_ADDR_W。在 s3c2410_hwcontrol 函数上一行定义这个全局变量,然后修改 s3c2410_hwcontrol 函数(修改71行),让它支持 S3C2440,如下:

[cpp]  view plain copy
  1. ulong IO_ADDR_W = NF_BASE;  
  2. static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)  
  3. {  
  4.     //struct nand_chip *chip = mtd->priv;  
  5.     struct s3c2410_nand *nand = s3c2410_get_base_nand();  
  6.   
  7.     debugX(1, "hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);  
  8.           
  9.     if (ctrl & NAND_CTRL_CHANGE) {  
  10.         //ulong IO_ADDR_W = (ulong)nand;  
  11.                 IO_ADDR_W = (ulong)nand;  
  12.   
  13.         if (!(ctrl & NAND_CLE))  
  14.             IO_ADDR_W |= S3C2410_ADDR_NCLE;  
  15.         if (!(ctrl & NAND_ALE))  
  16.             IO_ADDR_W |= S3C2410_ADDR_NALE;  
  17.   
  18.         //chip->IO_ADDR_W = (void *)IO_ADDR_W;  
  19.   
  20. #if defined(CONFIG_S3C2410)  
  21.         if (ctrl & NAND_NCE)  
  22.             writel(readl(&nand->NFCONF) & ~S3C2410_NFCONF_nFCE,  
  23.                    &nand->NFCONF);  
  24.         else  
  25.             writel(readl(&nand->NFCONF) | S3C2410_NFCONF_nFCE,  
  26.                    &nand->NFCONF);  
  27. #endif  
  28.   
  29. #if defined(CONFIG_S3C2440)  
  30.         if (ctrl & NAND_NCE)  
  31.             writel(readl(&nand->NFCONT) & ~S3C2410_NFCONT_nFCE,  
  32.                    &nand->NFCONT);  
  33.         else  
  34.             writel(readl(&nand->NFCONT) | S3C2410_NFCONT_nFCE,  
  35.                    &nand->NFCONT);  
  36. #endif  
  37.     }  
  38.   
  39.     if (cmd != NAND_CMD_NONE)  
  40.         //writeb(cmd, chip->IO_ADDR_W);  
  41.                 writeb(cmd, (void *)IO_ADDR_W);  
  42. }  

然后修改函数s3c2410_nand_enable_hwecc如下:

[cpp]  view plain copy
  1. void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)  
  2. {  
  3.     struct s3c2410_nand *nand = s3c2410_get_base_nand();  
  4.     debugX(1, "s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);  
  5. #if defined(CONFIG_S3C2410)  
  6.     writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);  
  7. #endif  
  8.   
  9. #if defined(CONFIG_S3C2440)  
  10.     writel(readl(&nand->NFCONT) | S3C2410_NFCONT_INITECC, &nand->NFCONT);  
  11. #endif  
  12. }  

最后修改board_nand_init 函数如下:

[cpp]  view plain copy
  1. int board_nand_init(struct nand_chip *nand)  
  2. {  
  3.     u_int32_t cfg;  
  4.     u_int8_t tacls, twrph0, twrph1;  
  5.     struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();  
  6.     struct s3c2410_nand *nand_reg = s3c2410_get_base_nand();  
  7.   
  8.     debugX(1, "board_nand_init()\n");  
  9.   
  10.     writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON);  
  11.   
  12. #if defined(CONFIG_S3C2410)  
  13.     /* initialize hardware */  
  14.     twrph0 = 3;  
  15.     twrph1 = 0;  
  16.     tacls = 0;  
  17.   
  18.     cfg = S3C2410_NFCONF_EN;  
  19.     cfg |= S3C2410_NFCONF_TACLS(tacls - 1);  
  20.     cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);  
  21.     cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);  
  22.     writel(cfg, &nand_reg->NFCONF);  
  23.   
  24.     /* initialize nand_chip data structure */  
  25.     nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;  
  26. #endif  
  27.   
  28. #if defined(CONFIG_S3C2440)  
  29.     /* initialize hardware */  
  30.     tacls = 0;  
  31.         twrph0 = 4;  
  32.     twrph1 = 2;  
  33.       
  34.   
  35.         cfg = 0;   
  36.         cfg |= S3C2410_NFCONF_TACLS(tacls - 1);   
  37.         cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);   
  38.         cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);   
  39.         writel(cfg, &nand_reg->NFCONF);   
  40.           
  41.         cfg = (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0);   
  42.         writel(cfg, &nand_reg->NFCONT);   
  43.         /* initialize nand_chip data structure */   
  44.         nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;  
  45. #endif  
  46.   
  47.     nand->select_chip = NULL;  
  48. ……  

source http://blog.csdn.net/yanghao23/article/details/7700699