MyException - 我的异常网
当前位置:我的异常网» Flash » u-boot-2014.10移栽第21天-添加nand flash命令支持

u-boot-2014.10移栽第21天-添加nand flash命令支持(三)

www.myexceptions.net  网友分享于:2015-02-08  浏览:0次
u-boot-2014.10移植第21天----添加nand flash命令支持(三)

硬件平台:tq2440

开发环境:Ubuntu-3.11

u-boot版本:2014.10

本文允许转载,请注明出处:http://blog.csdn.net/fulinus


虽说nand flash读写操作是可以了,但是我使用nand markbad命令将一个块标记为坏块时,再用nand scrub命令恢复出厂设置时,却出现了下面的错误:

nand0: MTD Erase failure: -5
说明我们的nand flash移植是不完全正确的。

下面查找原因

在文件drivers/mtd/nand/s3c2440_nand.c中开头部分只留下这些宏,前面说过了该文件中所有的2410字样的都改成了2440了,所以不要在下面修改时有什么觉得奇怪

#define S3C2440_NFCONF_TACLS(x)    ((x)<<12)
#define S3C2440_NFCONF_TWRPH0(x)   ((x)<<8)
#define S3C2440_NFCONF_TWRPH1(x)   ((x)<<4)


#define S3C2440_NFCONT_EN          (1<<0)
#define S3C2440_NFCONT_INITECC     (1<<4)
#define S3C2440_NFCONT_nFCE        (1<<1)
#define S3C2440_NFCONT_MAINECCLOCK (1<<5)


#define S3C2440_ADDR_NALE 8
#define S3C2440_ADDR_NCLE 0x0c

之前很多宏定义的是2410的nand flash寄存器的位,在2440上就有很多不同了,比如原来在NFCONF寄存器中的内容移到了NFCONT寄存器中去了。

修改s3c2440_hwcontrol函数中不再是S3C2440_NFCONF_nFCE宏,而是S3C2440_NFCONT_nFCE宏:

static void s3c2440_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
{
    struct nand_chip *chip = mtd->priv;
    struct s3c2440_nand *nand = s3c2440_get_base_nand();

    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 |= S3C2440_ADDR_NCLE;
        if (!(ctrl & NAND_ALE))
            IO_ADDR_W |= S3C2440_ADDR_NALE;

        if(cmd == NAND_CMD_NONE)
            IO_ADDR_W = (ulong)&nand->nfdata;

        chip->IO_ADDR_W = (void *)IO_ADDR_W;

        if (ctrl & NAND_NCE) /* 使能选中 */
            writel(readl(&nand->nfconf) & ~S3C2440_NFCONT_nFCE,
                   &nand->nfconf);        
        else /* 取消选中 */               
            writel(readl(&nand->nfconf) | S3C2440_NFCONT_nFCE,
                   &nand->nfconf);       
    }                                    
                                         
    if (cmd != NAND_CMD_NONE)            
        writeb(cmd, chip->IO_ADDR_W);    
}   


在s3c2440_nand_enable_hwecc函数中修改:

void s3c2440_nand_enable_hwecc(struct mtd_info *mtd, int mode)
{
    struct s3c2440_nand *nand = s3c2440_get_base_nand();
    debug("s3c2440_nand_enable_hwecc(%p, %d)\n", mtd, mode);
    writel(((readl(&nand->nfconf) | S3C2440_NFCONT_INITECC) & 
                (~S3C2440_NFCONT_MAINECCLOCK)), &nand->nfconf);
} 


在arch/arm/include/asm/arch-s3c24x0/s3c24x0.h 文件中修改:

/* NAND FLASH (see S3C2440 manual chapter 6) */
struct s3c2440_nand {
    u32 nfconf;
    u32 nfcont;
    u32 nfcmd;
    u32 nfaddr;
    u32 nfdata;
    u32 nfeccd0;
    u32 nfeccd1;
    u32 nfeccd;
    u32 nfstat;
    u32 nfstat0;
    u32 nfstat1;
    u32 nfmecc0;
    u32 nfmecc1;
    u32 nfsecc;
    u32 nfsblk;
    u32 nfeblk;
};

注:arch/arm/include/asm/目录下的arch目录其实是arch/arm/include/asm/arch-s3c24x0/目录的符号链接。
在s3c2440_nand_calculate_ecc函数中修改:

static int s3c2440_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
                      u_char *ecc_code)
{   
    struct s3c2440_nand *nand = s3c2440_get_base_nand();
    ecc_code[0] = readb(&nand->nfmecc0);
    ecc_code[1] = readb(&nand->nfmecc0 + 1);
    ecc_code[2] = readb(&nand->nfmecc0 + 2);
    ecc_code[3] = readb(&nand->nfmecc0 + 3);
    debug("s3c2440_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x 0x%02x\n",
           mtd , ecc_code[0], ecc_code[1], ecc_code[2], ecc_code[3]);
                                                       
    return 0;                                          
} 

在s3c2440_nand_correct_data函数中修改:

static int s3c2440_nand_correct_data(struct mtd_info *mtd, u_char *dat,
                     u_char *read_ecc, u_char *calc_ecc)
{
    struct s3c2440_nand *nand = s3c2440_get_base_nand();

    u32 estat0,err_byte_addr;
    int ret = -1;
    u8 repaired;

    writel((read_ecc[1] << 16) | read_ecc[0],&nand->nfeccd0);
    writel((read_ecc[3] << 16) | read_ecc[2],&nand->nfeccd1);

    /* Read ecc status */
    estat0= readl(&nand->nfstat);

    switch(estat0 & 0x3) {
        case  0: /* No error */
            ret= 0;
            break;

        case  1:
            /*
             * 1 bit error (Correctable)
             * (nfestat0 >> 7) & 0x7ff    :error byte number
             * (nfestat0 >> 4) & 0x7      :error bit number
             *
             */
            err_byte_addr= (estat0 >> 7) & 0x7ff;
            repaired= dat[err_byte_addr] ^ (1 << ((estat0 >> 4) & 0x7));

            printf("S3C NAND: 1 bit error detected at byte%d. "
                    "Correcting from 0x%02x to0x%02x...OK\n",
                    err_byte_addr, dat[err_byte_addr],repaired);

            dat[err_byte_addr]= repaired;

            ret= 1;
            break;

        case  2: /* Multiple error */
        case  3: /* ECC area error */
            printf("S3C NAND: ECC uncorrectable errordetected. "
                    "Not correctable.\n");
            ret= -1;
            break;
    }      
           
    return ret;
}          


删除s3c2440_nand_select函数:

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

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

    return;
}

在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 s3c2440_nand *nand_reg = s3c2440_get_base_nand();

    debug("board_nand_init()\n");

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

    /* initialize hardware */
    tacls = CONFIG_S3C24XX_TACLS;
    twrph0 = CONFIG_S3C24XX_TWRPH0;
    twrph1 = CONFIG_S3C24XX_TWRPH1;

    cfg = 0;
    cfg |= S3C2440_NFCONF_TACLS(tacls - 1);
    cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
    cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
    writel(cfg, &nand_reg->nfconf);

    /* 初始化ECC、禁止片选、使能NAND FLASH控制器 */
    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 = (void *)&nand_reg->nfdata;
    nand->IO_ADDR_W = (void *)&nand_reg->nfdata;

    nand->select_chip = NULL;

    /* read_buf and write_buf are default */
    /* read_byte and write_byte are default */
#ifdef CONFIG_NAND_SPL
    nand->read_buf = nand_read_buf;
#endif

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

    nand->dev_ready = s3c2440_dev_ready;

#ifdef CONFIG_S3C2440_NAND_HWECC
    nand->ecc.hwctl = s3c2440_nand_enable_hwecc;
    nand->ecc.calculate = s3c2440_nand_calculate_ecc;
    nand->ecc.correct = s3c2440_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_S3C2440_NAND_BBT
    nand->bbt_options |= NAND_BBT_USE_FLASH;
#endif      
    
    debug("end of nand_init\n");
    
    return 0;
}   

board_nand_init函数函数中涉及到几个宏需要在include/configs/tq2440.h文件中定义:

参考博文UBOOT移植(NAND FLASH的支持)——初步移植 (一) 

前面定义的CONFIG_SYS_S3C2440_NAND_HWECC宏名在s3c2440_nand.c文件中却是CONFIG_S3C2440_NAND_HWECC宏名,发现CONFIG_NAND_S3C2440宏也没有在哪里有用到,这里删除它。

在include/configs/tq2440.h文件中修改如下:

/*
 * NAND configuration
 */
#ifdef CONFIG_CMD_NAND

#define CONFIG_NAND_S3C2440
#define CONFIG_MTD_DEVICE
#define CONFIG_MTD_NAND_VERIFY_WRITE
#define CONFIG_SYS_NAND_MAX_CHIPS 1
#define CONFIG_SYS_MAX_NAND_DEVICE  1
#define CONFIG_SYS_NAND_BASE        0x4E000000

#define CONFIG_S3C24XX_CUSTOM_NAND_TIMING
#ifdef CONFIG_S3C24XX_CUSTOM_NAND_TIMING
#define CONFIG_S3C24XX_TACLS 0
#define CONFIG_S3C24XX_TWRPH0 4
#define CONFIG_S3C24XX_TWRPH1 2
#endif

#define CONFIG_S3C2440_NAND_HWECC
#ifdef CONFIG_S3C2440_NAND_HWECC
#define CONFIG_SYS_NAND_PAGE_SIZE 512
#define CONFIG_SYS_NAND_ECCSIZE CONFIG_SYS_NAND_PAGE_SIZE
#define CONFIG_SYS_NAND_ECCBYTES 4
#endif

#endif /* end CONFIG_CMD_NAND */

在drivers/mtd/nand/nand_base.c文件中修改nand_select_chip函数:

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

    switch (chipnr) {
    case -1:
        chip->cmd_ctrl(mtd, NAND_CMD_NONE, 0 | NAND_CTRL_CHANGE);
        break;
    case 0: /* 选中 */
        //chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_CTRL_CLE|NAND_CTRL_CHANGE);
        break;

    default:
        BUG();
    }
}

编译运行

情况依旧:

nand0: MTD Erase failure: -5

明天继续!















文章评论

编程语言是女人
编程语言是女人
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
Java程序员必看电影
Java程序员必看电影
每天工作4小时的程序员
每天工作4小时的程序员
2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
中美印日四国程序员比较
中美印日四国程序员比较
我的丈夫是个程序员
我的丈夫是个程序员
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
鲜为人知的编程真相
鲜为人知的编程真相
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
老程序员的下场
老程序员的下场
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
程序员和编码员之间的区别
程序员和编码员之间的区别
我是如何打败拖延症的
我是如何打败拖延症的
代码女神横空出世
代码女神横空出世
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
程序员的鄙视链
程序员的鄙视链
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
总结2014中国互联网十大段子
总结2014中国互联网十大段子
漫画:程序员的工作
漫画:程序员的工作
 程序员的样子
程序员的样子
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
程序员应该关注的一些事儿
程序员应该关注的一些事儿
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
那些争议最大的编程观点
那些争议最大的编程观点
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
旅行,写作,编程
旅行,写作,编程
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
如何成为一名黑客
如何成为一名黑客
程序员必看的十大电影
程序员必看的十大电影
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有