Chinaunix首页 | 论坛 | 博客
  • 博客访问: 152961
  • 博文数量: 22
  • 博客积分: 1456
  • 博客等级: 上尉
  • 技术积分: 252
  • 用 户 组: 普通用户
  • 注册时间: 2010-04-25 00:08
个人简介

ddd

文章存档

2011年(1)

2010年(21)

我的朋友

分类: 嵌入式

2010-04-25 13:57:57

4.1  Nand Flash 驱动

1)修改/drivers/mtd/nand/s3c2410_nand.c,原来的nand驱动在/cpu/arm920t/s3c24x0/nand.c中文件名和放置的位置都已经改变。

 

#define NF_BASE         0x4e000000

 

#if defined(CONFIG_S3C2410)

#define    NFCONF              __REGi(NF_BASE + 0x0)

#define    NFCMD         __REGb(NF_BASE + 0x4)

#define    NFADDR              __REGb(NF_BASE + 0x8)

#define    NFDATA        __REGb(NF_BASE + 0xc)

#define    NFSTAT         __REGb(NF_BASE + 0x10)

#define NFECC0           __REGb(NF_BASE + 0x14)

#define NFECC1           __REGb(NF_BASE + 0x15)

#define NFECC2           __REGb(NF_BASE + 0x16)

 

#define S3C2410_NFCONF_EN          (1<<15)

#define S3C2410_NFCONF_512BYTE     (1<<14)

#define S3C2410_NFCONF_4STEP       (1<<13)

#define S3C2410_NFCONF_INITECC     (1<<12)

#define S3C2410_NFCONF_nFCE        (1<<11)

#define S3C2410_NFCONF_TACLS(x)    ((x)<<8)

#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<4)

#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<0)

 

#define S3C2410_ADDR_NALE 4

#define S3C2410_ADDR_NCLE 8

#endif

 

#if defined(CONFIG_S3C2440)

#define S3C2410_ADDR_NALE 0x08

#define S3C2410_ADDR_NCLE 0x0c

 

#define    NFCONF              __REGi(NF_BASE + 0x0)

#define NFCONT        __REGb(NF_BASE + 0x4)  

#define    NFCMD         __REGb(NF_BASE + 0x8)

#define    NFADDR              __REGb(NF_BASE + 0xc)

#define    NFDATA        __REGb(NF_BASE + 0x10)

#define NFMECCD0    __REGb(NF_BASE + 0x14)

#define NFMECCD1    __REGb(NF_BASE + 0x18)

#define NFSECCD       __REGb(NF_BASE + 0x1c)

#define    NFSTAT         __REGb(NF_BASE + 0x20)

#define    NFESTAT0     __REGb(NF_BASE + 0x24)

#define    NFESTAT1     __REGb(NF_BASE + 0x28)

#define NFMECC0        __REGb(NF_BASE + 0x2c)

#define NFMECC1        __REGb(NF_BASE + 0x30)

#define NFSECC           __REGb(NF_BASE + 0x34)

#define NFSBLK           __REGb(NF_BASE + 0x38)

#define NFEBLK           __REGb(NF_BASE + 0x3c)

 

#define NFECC0           __REGb(NF_BASE + 0x2c)

#define NFECC1           __REGb(NF_BASE + 0x2d)

#define NFECC2           __REGb(NF_BASE + 0x2e)

 

#define S3C2410_NFCONT_EN          (1<<0)

#define S3C2410_NFCONT_INITECC     (1<<4)

#define S3C2410_NFCONT_nFCE        (1<<1)

#define S3C2410_NFCONT_MAINECCLOCK    (1<<5)

 

#define S3C2410_NFCONF_TACLS(x)    ((x)<<12)

#define S3C2410_NFCONF_TWRPH0(x)   ((x)<<8)

#define S3C2410_NFCONF_TWRPH1(x)   ((x)<<4)

 

#endif

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

 

ulong IO_ADDR_W = NF_BASE;

static void s3c2410_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) {

                //ulong IO_ADDR_W = NF_BASE;

                IO_ADDR_W = NF_BASE;

 

                if (!(ctrl & NAND_CLE))

                        IO_ADDR_W |= S3C2410_ADDR_NCLE;

                if (!(ctrl & NAND_ALE))

                        IO_ADDR_W |= S3C2410_ADDR_NALE;

 

                //chip->IO_ADDR_W = (void *)IO_ADDR_W;

 

#if defined(CONFIG_S3C2410)

                if (ctrl & NAND_NCE)

                        NFCONF &= ~S3C2410_NFCONF_nFCE;

                else

                        NFCONF |= S3C2410_NFCONF_nFCE;

}

#endif

#if defined(CONFIG_S3C2440)

                if (ctrl & NAND_NCE)

                        NFCONT &= ~S3C2410_NFCONT_nFCE;

                else

                        NFCONT |= S3C2410_NFCONT_nFCE;

        }

#endif

if (cmd != NAND_CMD_NONE)

                //writeb(cmd, chip->IO_ADDR_W);

                writeb(cmd, (void *)IO_ADDR_W);

 

}

 

#ifdef CONFIG_S3C2410_NAND_HWECC

void s3c2410_nand_enable_hwecc(struct mtd_info *mtd, int mode)

{

        DEBUGN("s3c2410_nand_enable_hwecc(%p, %d)\n", mtd, mode);

#if defined(CONFIG_S3C2410)

        NFCONF |= S3C2410_NFCONF_INITECC;

#endif

#if defined(CONFIG_S3C2440)

        NFCONT |= S3C2410_NFCONT_INITECC;

#endif

 

}

 

(3)修改board_nand_init 函数如下

int board_nand_init(struct nand_chip *nand)

{

        u_int32_t cfg;

        u_int8_t tacls, twrph0, twrph1;

        S3C24X0_CLOCK_POWER *const clk_power = S3C24X0_GetBase_CLOCK_POWER();

 

        DEBUGN("board_nand_init()\n");

 

        clk_power->CLKCON |= (1 << 4);

 

#if defined(CONFIG_S3C2410)

        /* initialize hardware */

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

 

        cfg = S3C2410_NFCONF_EN;

        cfg |= S3C2410_NFCONF_TACLS(tacls - 1);

        cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);

        cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);

 

        NFCONF = cfg;

 

        /* initialize nand_chip data structure */

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

 

#endif

 

#if defined(CONFIG_S3C2440)

        twrph0 = 4; twrph1 = 2; tacls = 0;

        cfg = 0;

        cfg |= S3C2410_NFCONF_TACLS(tacls - 1);

        cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);

        cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);

 

      NFCONF = cfg;

      NFCONT= (0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(0<<6)|(0<<5)|(1<<4)|(0<<1)|(1<<0);

        /* initialize nand_chip data structure */

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

#endif

        /* read_buf and write_buf are default */

        /* read_byte and write_byte are default */

 

阅读(2048) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~