您的位置:首页 > 其它

u-boot移植(六)添加nandflash支持

2011-12-25 20:36 281 查看
1、 添加nand flash 移植

mtd为linux下的存储架构,mtd封装了对存储器操作的统一接口函数,方便linux调用

查看lib_arm/boart.c文件,可以看到nand_init()函数在drivers/mtd/nand/nand.c中定义

#if defined(CONFIG_CMD_NAND)

puts ("NAND: ");

nand_init(); /* go init the NAND */

#endif

用sourceInsight查看,发现

a) 在include/s3c24x0.h中添加

typedef struct {

S3C24X0_REG32 NFCONF;

S3C24X0_REG32 NFCONT;

S3C24X0_REG32 NFCMD;

S3C24X0_REG32 NFADDR;

S3C24X0_REG32 NFDATA;

3C24X0_REG32 NFMECCD0;

3C24X0_REG32 NFMECCD1;

3C24X0_REG32 NFSECCD;

3C24X0_REG32 NFSTAT;

3C24X0_REG32 NFESTAT0;

3C24X0_REG32 NFESTAT1;

3C24X0_REG32 NFMECC0;

3C24X0_REG32 NFMECC1;

3C24X0_REG32 NFSECC;

3C24X0_REG32 NFSBLK;

3C24X0_REG32 NFEBLK;

} S3C2440_NAND;

在include/s3c2410.h中添加

#define S3C2440_NAND_BASE 0x4E000000

static inline S3C2440_NAND * S3C2440_GetBase_NAND(void)

{

return (S3C2440_NAND * const)S3C2440_NAND_BASE;

}

b) Include/configs/mini2440.h

修改1:添加对nand的支持,添加

#define CONFIG_CMD_NAND

#define CONFIG_MAX_NAND_DEVICE 1

#define CONFIG_SYS_NAND_BASE 0x4E000000

#define CONFIG_MTD_DEVICE选项可以不加,只是对nand info命令有影响

c) drivers/mtd/nand/s3c2410_nand.c

修改1:注释掉源文件开始的所有寄存器定义,添加

#define NFCONF __REGi(NF_BASE + 0x0)

#define NFCONT __REGi(NF_BASE + 0X4)

#define NFCMD __REGb(NF_BASE + 0x8)

#define NFADDR __REGb(NF_BASE + 0xC)

#define NFDATA __REGb(NF_BASE + 0x10)

#define NFSTAT __REGb(NF_BASE + 0x20)

#define NFECC0 __REGb(NF_BASE + 0x14)

#define NFECC1 __REGb(NF_BASE + 0x18)

#define NFSECC __REGb(NF_BASE + 0x1C)

#define S3C2440_NFCONT_EN (1<<0)

#define S3C2440_NFCONT_nFCE (0<<1)

#define S3C2440_NFCONT_INITECC (1<<4)

#define S3C2440_NFCONF_TACLS(x) ((x)<<12)

#define S3C2440_NFCONF_TWRPH0(x) ((x)<<8)

#define S3C2440_NFCONF_TWRPH1(x) ((x)<<4)

#define S3C2440_NFCONT_nCE (1<<1)

#define S3C2440_ADDR_NALE 0x0c

#define S3C2440_ADDR_NCLE 0x08

修改2:修改函数s3c2410_hwcontrol如下

static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)

{

struct nand_chip *chip = mtd->priv;//可加可不加

ulong IO_ADDR_W = NF_BASE;

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;

else

NFCONT |= S3C2440_NFCONT_nCE;

}

if (cmd != NAND_CMD_NONE)

writeb(cmd, (void *)IO_ADDR_W);

}

个人认为全局变量IO_ADDR_W可以换成其他变量名

修改3:board_nand_init函数,首先设置NFCONF,NFCONT寄存器的值,并确定nand读写的NFDATA寄存器,

twrph0 =5; twrph1 = 3; tacls = 0;

cfg = S3C2440_NFCONF_TACLS(tacls - 1);

cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);

cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);

NFCONF = cfg;

cfg = S3C2440_NFCONT_EN;

cfg |= S3C2440_NFCONT_nFCE;

cfg |= S3C2440_NFCONT_INITECC;

NFCONT = cfg;

设置mtd_info中IO_ADDR_W和IO_ADDR_R值,

nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;

并设置命令解析函数和等待空闲函数,正常结束返回0值。

nand->cmd_ctrl = s3c2410_hwcontrol;

nand->dev_ready = s3c2410_dev_ready;

修改4 :进入顶层目录编译工程,出现undefined reference to `board_nand_init',查看drivers/mtd/nand/Makefile文件,看到

COBJS-$(CONFIG_NAND_NDFC) += ndfc.o

COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o

COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o

COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o

所以需要定义#define CONFIG_NAND_S3C2410这个宏,并重新编译,下载到板子上测试,

修改5:修改nandflash读写时序,drivers/mtd/nand/s3c2410_nand.c

twrph0 = 4; twrph1 = 2; tacls = 0;,下载擦除还有问题,仔细研究代码,经过仔细分析源代码,发现源代码hwcontrol中的IO_ADDR_W并不是mtd_info结构体中的IO_ADDR_W,其在此处作用只是辅助解析cmd命令。为了使代码更清晰,把其换为nand_addr

ulong nand_addr = NF_BASE;

static void s3c2410_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)

{

if (ctrl & NAND_CTRL_CHANGE) {

nand_addr = NF_BASE;

if (!(ctrl & NAND_CLE))

nand_addr |= S3C2440_ADDR_NALE;

if (!(ctrl & NAND_ALE))

nand_addr |= S3C2440_ADDR_NCLE;

if (ctrl & NAND_NCE)

NFCONT &=~S3C2440_NFCONT_nCE;

else

NFCONT |=S3C2440_NFCONT_nCE;

}

if (cmd != NAND_CMD_NONE)

writeb(cmd, (void *)nand_addr);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: