u-boot移植2:支持 nandflash 的读写

u-boot 版本:2016.03
用的交叉编译工具:arm-none-linux-gnueabi-

操作的文件: drivers/mtd/nand/s3c2440_nand.c

1. 修改 s3c2440 的 nandflash 的控制器


@@ -11,17 +11,17 @@
 #include <asm/arch/s3c24x0_cpu.h>
 #include <asm/io.h>

-#define S3C2440_NFCONF_EN          (1<<15)
-#define S3C2440_NFCONF_512BYTE     (1<<14)
-#define S3C2440_NFCONF_4STEP       (1<<13)
-#define S3C2440_NFCONF_INITECC     (1<<12)
-#define S3C2440_NFCONF_nFCE        (1<<11)
-#define S3C2440_NFCONF_TACLS(x)    ((x)<<8)
-#define S3C2440_NFCONF_TWRPH0(x)   ((x)<<4)
-#define S3C2440_NFCONF_TWRPH1(x)   ((x)<<0)
-
-#define S3C2440_ADDR_NALE 4
-#define S3C2440_ADDR_NCLE 8
+#define S3C2440_NFCONT_SECCL          (1<<6)
+#define S3C2440_NFCONT_MECCL          (1<<5)
+#define S3C2440_NFCONT_INITECC        (1<<4)
+#define S3C2440_NFCONT_nCE            (1<<1)
+#define S3C2440_NFCONT_MODE           (1<<0)
+#define S3C2440_NFCONF_TACLS(x)       ((x)<<12)
+#define S3C2440_NFCONF_TWRPH0(x)      ((x)<<8)
+#define S3C2440_NFCONF_TWRPH1(x)      ((x)<<4)
+
+#define S3C2440_ADDR_NALE 0x08
+#define S3C2440_ADDR_NCLE 0x0c

 #ifdef CONFIG_NAND_SPL

2. 修改 s3c24x0_hwcontrol():


说明
  • 该函数是用于对 nandflash 的写命令和写地址操作
  • 添加 if(cmd == NAND_CMD_NONE)判断语句。如果不加这个判断语句,向NandFlash内写数据是写不进去的,因为在写完命令和地址后,一定还要把IO端口的地址重新设置为寄存器NFDATA。
  • 系统没有定义CONFIG_S3C2410_NAND_HWECC,因此我们暂时先不对s3c2440_nand_enable_hwecc函数、s3c2440_nand_calculate_ecc函数和s3c2440_nand_correct_data函数进行修改。

@@ -53,13 +53,16 @@ static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
                if (!(ctrl & NAND_ALE))
                        IO_ADDR_W |= S3C2440_ADDR_NALE;

-               chip->IO_ADDR_W = (void *)IO_ADDR_W;
+        if (cmd == NAND_CMD_NONE)
+            IO_ADDR_W = (ulong)&nand->nfdata;
+        
+        chip->IO_ADDR_W = (void *)IO_ADDR_W;

                if (ctrl & NAND_NCE)
-                       writel(readl(&nand->nfconf) & ~S3C2440_NFCONF_nFCE,
+                       writel(readl(&nand->nfconf) & ~S3C2440_NFCONT_nCE,
                               &nand->nfconf);
                else
-                       writel(readl(&nand->nfconf) | S3C2440_NFCONF_nFCE,
+                       writel(readl(&nand->nfconf) | S3C2440_NFCONT_nCE,
                               &nand->nfconf);
        }

3. 和 board_nand_init() 函数:


说明
  • 此函数是对寄存器 NFCONF 和 NFCONT 的修改

@@ -125,17 +128,21 @@ int board_nand_init(struct nand_chip *nand)
        twrph0 = CONFIG_S3C24XX_TWRPH0;
        twrph1 =  CONFIG_S3C24XX_TWRPH1;
 #else
-       tacls = 4;
-       twrph0 = 8;
-       twrph1 = 8;
+       tacls = 2;
+       twrph0 = 3;
+       twrph1 = 1;
 #endif

-       cfg = S3C2440_NFCONF_EN;
-       cfg |= S3C2440_NFCONF_TACLS(tacls - 1);
+       cfg = S3C2440_NFCONF_TACLS(tacls - 1);
        cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
        cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
        writel(cfg, &nand_reg->nfconf);

+    cfg = S3C2440_NFCONT_SECCL;
+    cfg |= S3C2440_NFCONT_MECCL;
+    cfg |= S3C2440_NFCONT_MODE;
+       writel(cfg, &nand_reg->nfcont);
+
        /* initialize nand_chip data structure */
        nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
        nand->IO_ADDR_W = (void *)&nand_reg->nfdata;

4. 验证:


思路:
  • 选中device 0
  • 擦除 nandflash 的从 0x100000 地址开始的 0x300000 大小的区域
  • 强 sdram 的从 0 地址开始的0x300000 大小的内容写到nandflash中从 0x100000 开始的地址上去
  • 读取 nandflash 从 0x100000 开始的大小 0x300000 的内容到 sdram 的 0x30004000位置上
  • 读取 sdram 上的 从0 开始的默认大小的数据 和 sdram 上的 从 0x30004000 开始的默认大小的数据,并且以字节方式显示,看看他们是不是一样,如果一样,说明读和写都是没有问题的

U-Boot 2016.03-00001-g79e6686-dirty (May 05 2016 - 14:40:05 +0800)
CPUID: 32440001
FCLK:      400 MHz
HCLK:      100 MHz
PCLK:       50 MHz
DRAM:  64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND:  256 MiB
*** Warning - bad CRC, using default environment
In:    serial
Out:   serial
Err:   serial
Net:   CS8900-0
Error: CS8900-0 address not set.
LIP2440 # nand info

Device 0: nand0, sector size 128 KiB
  Page size       2048 b
  OOB size          64 b
  Erase size    131072 b
  subpagesize      512 b
  options     0x    1008
  bbt options 0x    8000
LIP2440 #  nand device 0
LIP2440 #  nand erase 100000 300000
NAND erase: device 0 offset 0x100000, size 0x300000
Erasing at 0x3e0000 -- 100% complete.
OK
LIP2440 #  nand write 0 100000 300000
NAND write: device 0 offset 0x100000, size 0x300000
 3145728 bytes written: OK
LIP2440 #  nand read 30004000 100000 300000
NAND read: device 0 offset 0x100000, size 0x300000
 3145728 bytes read: OK
LIP2440 #  md.b 0
00000000: be 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5    ................
00000010: 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5    ................
00000020: 60 00 00 00 c0 00 00 00 20 01 00 00 80 01 00 00    `....... .......
00000030: e0 01 00 00 40 02 00 00 a0 02 00 00 ef be ad de    ....@...........
LIP2440 #  md.b 30004000
30004000: be 00 00 ea 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5    ................
30004010: 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5 14 f0 9f e5    ................
30004020: 60 00 00 00 c0 00 00 00 20 01 00 00 80 01 00 00    `....... .......
30004030: e0 01 00 00 40 02 00 00 a0 02 00 00 ef be ad de    ....@...........
LIP2440 # 

你可能感兴趣的:(uboot,NANDflash,nandflash读写,uboot2016.03)