u-boot-2016.05移植:(4)、支持NADN FLASH

1、在u-boot-2016.05\drivers\mtd\nand文件夹中拷贝一份s3c2410_nand.c并重命名s3c2440_nand.c。那么如何决定将s3c2440_nand.c和s3c2410_nand.c哪个编译进程序?
首先在u-boot-2016.05\include\configs\smdk2440.h中将

/*
 * NAND configuration
 */
#ifdef CONFIG_CMD_NAND
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#define CONFIG_SYS_MAX_NAND_DEVICE  1
#define CONFIG_SYS_NAND_BASE        0x4E000000
#endif

中的

#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC

改为

#ifdef CONFIG_S3C2410
#define CONFIG_NAND_S3C2410
#define CONFIG_SYS_S3C2410_NAND_HWECC
#else
#define CONFIG_NAND_S3C2440
#define CONFIG_SYS_S3C2440_NAND_HWECC
#endif

然后,在u-boot-2016.05\drivers\mtd\nand\Makefile文件中的

obj-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o

之后添加一项

obj-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

因为宏定义了CONFIG_NAND_S3C2440而没宏定义CONFIG_NAND_S3C2410,所以,这样编译进u-boot就是s3c2440_nand.c文件。
2、在u-boot-2016.05\drivers\mtd\nand\s3c2440_nand.c:board_nand_init函数中用

/* 设置时序 */
cfg = ((tacls-1)<<12)|((twrph0-1)<<8)|((twrph1-1)<<4);

替换

cfg = S3C2410_NFCONF_EN;
cfg |= S3C2410_NFCONF_TACLS(tacls - 1);
cfg |= S3C2410_NFCONF_TWRPH0(twrph0 - 1);
cfg |= S3C2410_NFCONF_TWRPH1(twrph1 - 1);

紧接着后面添加

/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */
writel((1<<4)|(1<<1)|(1<<0), &nand_reg->nfcont);    

再用

nand->select_chip = s3c2440_nand_select;

替换

nand->select_chip = NULL;

然后在board_nand_init函数前边添加片选函数s3c2440_nand_select:

static void s3c2440_nand_select(struct mtd_info *mtd, int chipnr)
{
    struct s3c24x0_nand *nand = s3c24x0_get_base_nand();

    switch (chipnr) {
    case -1:        /*取消选中*/
        nand->nfcont |= (1<<1);
        break;
    case 0:     /*选中*/
        nand->nfcont &= ~(1<<1);
        break;

    default:
        BUG();
    }
}

3、在u-boot-2016.05\drivers\mtd\nand\s3c2440_nand.c:s3c24x0_hwcontrol函数中删掉

    struct nand_chip *chip = mtd->priv;
    debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);

    if (ctrl & NAND_CTRL_CHANGE) {
        ulong 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 (ctrl & NAND_NCE)
            writel(readl(&nand->nfconf) & ~S3C2410_NFCONF_nFCE,
                   &nand->nfconf);
        else
            writel(readl(&nand->nfconf) | S3C2410_NFCONF_nFCE,
                   &nand->nfconf);
    }

    if (cmd != NAND_CMD_NONE)
        writeb(cmd, chip->IO_ADDR_W);

添加

    if (ctrl & NAND_CLE)
        {
            writeb(cmd, &nand->nfcmd);
        }
    else if (ctrl & NAND_ALE)
        {
            writeb(cmd, &nand->nfaddr);
        }

编译烧写到NAND FLASH就可以识别NAND大小。
4、分析过程:

u-boot-2016.05\common\board_r:board_init_r函数中的初始化序列init_sequence_r中的:
initr_nand
    nand_init
        nand_init_chip
            board_nand_init
                设置nand_chip结构体, 提供底层的操作函数
            nand_scan
                nand_scan_ident
                    nand_set_defaults
                        chip->select_chip = nand_select_chip;
                        chip->cmdfunc = nand_command;
                        chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;

                    nand_get_flash_type
                        chip->select_chip
                        chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
                                nand_command()  // 即可以用来发命令,也可以用来发列地址(页内地址)、行地址(哪一页)
                                    chip->cmd_ctrl
                                            s3c24x0_hwcontrol

                        chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
                        *maf_id = chip->read_byte(mtd);
                        *dev_id = chip->read_byte(mtd);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值