社区导航

 
查看: 3053|回复: 0

[原创] TQ210实现nandflash移植

[复制链接]

1315

TA的帖子

0

TA的资源

版主

Rank: 6Rank: 6

发表于 2018-5-11 17:35:53 | 显示全部楼层 |阅读模式
移植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 <common.h>

#include <nand.h>
#include <asm/arch/nand_reg.h>
#include <asm/io.h>

#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)
编译下载,如图
   捕获.JPG
有警告啊,使用命令saveenv 将环境变量保存到 NAND 中,下次启动就不会有那样的警告了
   捕获1.JPG
重启结果是

捕获2.JPG

今天就这样了。



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

此帖出自ARM技术论坛


回复

使用道具 举报

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

本版积分规则

  • 论坛活动 E手掌握

    扫码关注
    EEWORLD 官方微信

  • EE福利  唾手可得

    扫码关注
    EE福利 唾手可得

小黑屋|手机版|Archiver|电子工程世界 ( 京ICP证 060456

GMT+8, 2018-8-21 06:55 , Processed in 0.051315 second(s), 17 queries , Gzip On, Redis On.

快速回复 返回顶部 返回列表