Chinaunix首页 | 论坛 | 博客
  • 博客访问: 71380
  • 博文数量: 25
  • 博客积分: 116
  • 博客等级: 民兵
  • 技术积分: 135
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-26 11:31
文章分类
文章存档

2013年(1)

2012年(24)

我的朋友

分类:

2012-08-09 10:34:15

移植U-Boot-2010.03到友善之臂mini2440(四)

 

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

 

#define S3C2410_ADDR_NALE 0x08

#define S3C2410_ADDR_NCLE 0x0c

#endif

 

(2)u-boot.2010.03自带的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;

  struct s3c2410_nand *nand = s3c2410_get_base_nand();

 

  debugX(1, "hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);

      

 

             if (ctrl & NAND_CTRL_CHANGE) {

                //ulong IO_ADDR_W = (ulong)nand;

                IO_ADDR_W = (ulong)nand;

 

                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)

              writel(readl(&nand->NFCONF) & ~S3C2410_NFCONF_nFCE,

                     &nand->NFCONF);

       else

              writel(readl(&nand->NFCONF) | S3C2410_NFCONF_nFCE,

                     &nand->NFCONF);

  }

#endif

 

#if defined(CONFIG_S3C2440)

       if (ctrl & NAND_NCE)

              writel(readl(&nand->NFCONT) & ~S3C2410_NFCONT_nFCE,

                     &nand->NFCONT);

       else

              writel(readl(&nand->NFCONT) | S3C2410_NFCONT_nFCE,

                     &nand->NFCONT);

  }

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

 

//writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);

 

#if defined(CONFIG_S3C2410)

              writel(readl(&nand->NFCONF) | S3C2410_NFCONF_INITECC, &nand->NFCONF);

#endif

#if defined(CONFIG_S3C2440)

  writel(readl(&nand->NFCONT) | S3C2410_NFCONT_INITECC, &nand->NFCONT);

#endif

}

 

(3)修改board_nand_init 函数如下

int board_nand_init(struct nand_chip *nand)

{

  u_int32_t cfg;

  u_int8_t tacls, twrph0, twrph1;

  struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();

  struct s3c2410_nand *nand_reg = s3c2410_get_base_nand();

  debugX(1, "board_nand_init()\n");

  writel(readl(&clk_power->CLKCON) | (1 << 4), &clk_power->CLKCON);

 

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

  writel(cfg, &nand_reg->NFCONF);

 

  /* initialize nand_chip data structure */

  nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;

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

  writel(cfg, &nand_reg->NFCONF);

 

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

  writel(cfg, &nand_reg->NFCONT);

 

  /* initialize nand_chip data structure */

  nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)&nand_reg->NFDATA;

#endif

 

        nand->select_chip = NULL;

        /* read_buf and write_buf are default */

        /* read_byte and write_byte are default */

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