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

来源:互联网 发布:unity3d培训机构那个好 编辑:程序博客网 时间:2024/06/05 03:59
 

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);

}

原创粉丝点击