u-boot-2011.03在mini2440/micro2440上的移植(五)——支持Nand Flash

5.1 添加s3c2440_nand.c

[408@WZC u-boot-2011.03]$ touch drivers/mtd/nand/s3c2440_nand.c 
[408@WZC u-boot-2011.03]$ cat> drivers/mtd/nand/s3c2440_nand.c

#include <common.h>

#if 0
#define DEBUGN    printf
#else
#define DEBUGN(x, args ...) {}
#endif

#include <nand.h>
#include <asm/arch/s3c24x0_cpu.h>
#include <asm/io.h>

#define __REGb(x)    (*(volatile unsigned char *)(x))
#define __REGi(x)    (*(volatile unsigned int *)(x))

#define NF_BASE  0x4e000000             //Nand配置寄存器基地址
#define NFCONF   __REGi(NF_BASE + 0x0)  //偏移後還是得到配置寄存器基地址
#define NFCONT   __REGi(NF_BASE + 0x4)  //偏移後得到Nand控制寄存器基地址
#define NFCMD    __REGb(NF_BASE + 0x8)  //偏移後得到Nand指令寄存器基地址
#define NFADDR   __REGb(NF_BASE + 0xc)  //偏移後得到Nand地址寄存器基地址
#define NFDATA   __REGb(NF_BASE + 0x10) //偏移後得到Nand數據寄存器基地址
#define NFMECCD0 __REGi(NF_BASE + 0x14) //偏移後得到Nand主數據區域ECC0寄存器基地址
#define NFMECCD1 __REGi(NF_BASE + 0x18) //偏移後得到Nand主數據區域ECC1寄存器基地址
#define NFSECCD  __REGi(NF_BASE + 0x1C) //偏移後得到Nand空閒區域ECC寄存器基地址
#define NFSTAT   __REGb(NF_BASE + 0x20) //偏移後得到Nand狀態寄存器基地址
#define NFSTAT0  __REGi(NF_BASE + 0x24) //偏移後得到Nand ECC0狀態寄存器基地址
#define NFSTAT1  __REGi(NF_BASE + 0x28) //偏移後得到Nand ECC1狀態寄存器基地址
#define NFMECC0  __REGi(NF_BASE + 0x2C) //偏移後得到Nand主數據區域ECC0狀態寄存器基地址
#define NFMECC1  __REGi(NF_BASE + 0x30) //偏移後得到Nand主數據區域ECC1狀態寄存器基地址
#define NFSECC   __REGi(NF_BASE + 0x34) //偏移後得到Nand空閒區域ECC狀態寄存器基地址
#define NFSBLK   __REGi(NF_BASE + 0x38) //偏移後得到Nand塊開始地址
#define NFEBLK   __REGi(NF_BASE + 0x3c) //偏移後得到Nand塊結束地址

#define S3C2440_NFCONT_nCE  (1<<1)
#define S3C2440_ADDR_NALE   0x0c
#define S3C2440_ADDR_NCLE   0x08

ulong IO_ADDR_W = NF_BASE;

static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
 struct nand_chip *chip = mtd->priv;

 DEBUGN("hwcontrol(): 0x%02x 0x%02x/n", cmd, ctrl);

 if (ctrl & NAND_CTRL_CHANGE)
 {
  IO_ADDR_W = NF_BASE;

  if (!(ctrl & NAND_CLE))                //要寫的是地址
   IO_ADDR_W |= S3C2440_ADDR_NALE;
  if (!(ctrl & NAND_ALE))                //要寫的是命令
   IO_ADDR_W |= S3C2440_ADDR_NCLE;

  if (ctrl & NAND_NCE) 
   NFCONT &= ~S3C2440_NFCONT_nCE;    //使能nand flash
  else
   NFCONT |= S3C2440_NFCONT_nCE;     //禁止nand flash
 }

 if (cmd != NAND_CMD_NONE)
  writeb(cmd,(void *)IO_ADDR_W);
}

static int s3c2440_dev_ready(struct mtd_info *mtd)
{
 DEBUGN("dev_ready/n");
 return (NFSTAT & 0x01);
}

int board_nand_init(struct nand_chip *nand)
{
 u_int32_t cfg;
 u_int8_t tacls, twrph0, twrph1;
 struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power();

 DEBUGN("board_nand_init()/n");

 tacls = 1;

 twrph0 = 2; 

 twrph1 = 1; 

 cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);
 NFCONF = cfg;

 cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);
 NFCONT = cfg;

 /* initialize nand_chip data structure */
 nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;

 /* read_buf and write_buf are default */
 /* read_byte and write_byte are default */

 /* hwcontrol always must be implemented */
 nand->cmd_ctrl = s3c2440_hwcontrol;

 nand->dev_ready = s3c2440_dev_ready;

 return 0;
}

 【說明】

經過幾次測試,yaffs2寫入不太穩定,修改上面紅色部分後,yaffs2寫入正常

5.2 drivers/mtd/nand/Makefile

COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

 

5.3 include/conskfigs/micro2440.h

添加

#define CONFIG_MTD_DEVICE
#define CONFIG_NAND_S3C2440
#define CONFIG_CMD_NAND
#if defined(CONFIG_CMD_NAND)
#define CONFIG_SYS_NAND_BASE            0x4E000000 //Nand配置寄存器基地址
#define CONFIG_SYS_MAX_NAND_DEVICE      1
#define CONFIG_MTD_NAND_VERIFY_WRITE    1

#endif

 

#define CONFIG_ENV_IS_IN_NAND  1
#define CONFIG_ENV_OFFSET      0x40000 //將環境變量保存到nand中的0x40000位置
#define CONFIG_ENV_SIZE        0x10000 /* Total Size of Environment Sector */

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章