5267|0

1903

帖子

0

TA的资源

版主

楼主
 

TQ210实现nandflash移植 [复制链接]

移植NAND FLASH比较麻烦,需要改动的地方很多,下面简要是说明一下
首先在u-boot-2014.04\include\configs\smdkv210.h里面

#define CONFIG_ENV_IS_IN_ONENAND        1
换成
#define CONFIG_ENV_IS_IN_NAND
新增
#define CONFIG_SYS_MAX_NAND_DEVICE         1
#define CONFIG_SYS_NAND_BASE                0xB0E00000
#define CONFIG_NAND_S5PV210

#define CONFIG_ENV_IS_IN_ONENAND        1
改成
#define CONFIG_ENV_IS_IN_NAND


在u-boot-2014.04\drivers\mtd\nand里面
拷贝s3c2410_nand.c改名为s5pv210_nand.c,里面的内容需要更改,参考2410的更改就行,直接上代码,更改的太多了。
/*
* (C) Copyright 2006 OpenMoko, Inc.
* Author: Harald Welte <laforge@openmoko.org>
*
* SPDX-License-Identifier:        GPL-2.0+
*/

#include

#include
#include
#include

#define MP0_1CON  (*(volatile u32 *)0xE02002E0)
#define        MP0_3CON  (*(volatile u32 *)0xE0200320)
#define        MP0_6CON  (*(volatile u32 *)0xE0200380)

static void s5pv210_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
        struct nand_chip *chip = mtd->priv;
        struct s5pv210_nand *nand = (struct s5pv210_nand *)samsung_get_base_nand();
        debug("hwcontrol(): 0x%02x 0x%02x\n", cmd, ctrl);
        ulong IO_ADDR_W = (ulong)nand;
        if (ctrl & NAND_CTRL_CHANGE) {

                if (ctrl & NAND_CLE)               
                        IO_ADDR_W = IO_ADDR_W | 0x8;        /* Command Register  */
                else if (ctrl & NAND_ALE)
                        IO_ADDR_W = IO_ADDR_W | 0xC;        /* Address Register */

                chip->IO_ADDR_W = (void *)IO_ADDR_W;

                if (ctrl & NAND_NCE)        /* select */
                        writel(readl(&nand->nfcont) & ~(1 << 1), &nand->nfcont);
                else                                        /* deselect */
                        writel(readl(&nand->nfcont) | (1 << 1), &nand->nfcont);
        }

        if (cmd != NAND_CMD_NONE)
                writeb(cmd, chip->IO_ADDR_W);        
        else
                chip->IO_ADDR_W = &nand->nfdata;

}

static int s5pv210_dev_ready(struct mtd_info *mtd)
{
        struct s5pv210_nand *nand = (struct s5pv210_nand *)samsung_get_base_nand();
        debug("dev_ready\n");
        return readl(&nand->nfstat) & 0x01;
}


void s5pv210_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
        struct s5pv210_nand *nand = (struct s5pv210_nand *)samsung_get_base_nand();
        debug("s5pv210_nand_enable_hwecc(%p, %d)\n", mtd, mode);
        writel(readl(&nand->nfconf) | S3C2410_NFCONF_INITECC, &nand->nfconf);
}

static int s5pv210_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
                                      u_char *ecc_code)
{
        struct s5pv210_nand *nand = (struct s5pv210_nand *)samsung_get_base_nand();
        ecc_code[0] = readb(&nand->nfecc);
        ecc_code[1] = readb(&nand->nfecc + 1);
        ecc_code[2] = readb(&nand->nfecc + 2);
        debug("s5pv210_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x\n",
               mtd , ecc_code[0], ecc_code[1], ecc_code[2]);

        return 0;
}

static int s5pv210_nand_correct_data(struct mtd_info *mtd, u_char *dat,
                                     u_char *read_ecc, u_char *calc_ecc)
{
        if (read_ecc[0] == calc_ecc[0] &&
            read_ecc[1] == calc_ecc[1] &&
            read_ecc[2] == calc_ecc[2])
                return 0;

        printf("s5pv210_nand_correct_data: not implemented\n");
        return -1;
}
#endif


static void s5pv210_nand_select_chip(struct mtd_info *mtd, int ctl)
{
        struct nand_chip *chip = mtd->priv;

        switch (ctl) {
        case -1:        /* deselect the chip */
                chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
                break;
        case 0:                /* Select the chip */
                chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
                break;

        default:
                BUG();
        }
}

int board_nand_init(struct nand_chip *nand)
{
        u32 cfg;
        struct s5pv210_nand *nand_reg = (struct s5pv210_nand *)(struct s5pv210_nand *)samsung_get_base_nand();

        debug("board_nand_init()\n");

        /* initialize hardware */
        /* HCLK_PSYS=133MHz(7.5ns) */
        cfg =        (0x1 << 23) |        /* Disable 1-bit and 4-bit ECC */
                        /* 下面3个时间参数稍微比计算出的值大些(我这里依次加1),否则读写不稳定 */
                        (0x3 << 12) |        /* 7.5ns * 2 > 12ns tALS tCLS */
                        (0x2 << 8) |         /* (1+1) * 7.5ns > 12ns (tWP) */
                        (0x1 << 4) |         /* (0+1) * 7.5 > 5ns (tCLH/tALH) */
                        (0x0 << 3) |         /* SLC NAND Flash */
                        (0x0 << 2) |        /* 2KBytes/Page */
                        (0x1 << 1);                /* 5 address cycle */

        writel(cfg, &nand_reg->nfconf);

        writel((0x1 << 1) | (0x1 << 0), &nand_reg->nfcont);
        /* Disable chip select and Enable NAND Flash Controller */

        /* Config GPIO */
        MP0_1CON &= ~(0xFFFF << 8);
        MP0_1CON |= (0x3333 << 8);
        MP0_3CON = 0x22222222;
        MP0_6CON = 0x22222222;

        /* initialize nand_chip data structure */
        nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
        nand->IO_ADDR_W = (void *)&nand_reg->nfdata;

        nand->select_chip = s5pv210_nand_select_chip;

        /* read_buf and write_buf are default */
        /* read_byte and write_byte are default */

        /* hwcontrol always must be implemented */
        nand->cmd_ctrl = s5pv210_hwcontrol;

        nand->dev_ready = s5pv210_dev_ready;

#ifdef CONFIG_S3C2410_NAND_HWECC
        nand->ecc.hwctl = s5pv210_nand_enable_hwecc;
        nand->ecc.calculate = s5pv210_nand_calculate_ecc;
        nand->ecc.correct = s5pv210_nand_correct_data;
        nand->ecc.mode = NAND_ECC_HW;
        nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
        nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
        nand->ecc.strength = 1;
#else
        nand->ecc.mode = NAND_ECC_SOFT;
#endif

#ifdef CONFIG_S3C2410_NAND_BBT
        nand->bbt_options |= NAND_BBT_USE_FLASH;
#endif

        debug("end of nand_init\n");

        return 0;
}

同时,目录下面的Makefile里面新增
obj-$(CONFIG_NAND_S5PV210) += s5pv210_nand.o
在u-boot-2014.04-5\arch\arm\include\asm\arch-s5pc1xx\cup.h里面新增
#define S5PV210_NAND_BASE        0xB0E00000
SAMSUNG_BASE(nand, NAND_BASE)
编译下载,如图
  
有警告啊,使用命令saveenv 将环境变量保存到 NAND 中,下次启动就不会有那样的警告了
  
重启结果是



今天就这样了。



此内容由EEWORLD论坛网友star_66666原创,如需转载或用于商业用途需征得作者同意并注明出处

此帖出自ARM技术论坛
点赞 关注
 

回复
举报
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表