NandFlash控制器

NandFlash控制器
本文以MT29F4G08ABADA 型号为例
MT29F4G08ABADA容量为4Gbit
1page=(2K+64)byte
1block=(2K+64)64page=(128K+4K)byte
1plane=(128K+4K)2048block=2112Mbit
1device=2112Mbit
2
地址序列如下
在这里插入图片描述
CAx为列地址; PAx =页地址; BAx = block地址
命令,地址,数据都通过8个IO口输入/输出。写入命令、数据、地址时,都需要将WE#、CE#信号同时拉低。数据在WE#信号的上升沿被NAND Flash锁存。命令锁存信号CLE和地址锁存信号ALE用于分辨、锁存命令或地址。MT89F4G08ABADA需要34位地址。读写命令需要发送5个地址序列。具体命令可以参考MT29F4G08ABADA数据手册。接下来将会对nand flash的ECC校验做个简要讲解,NandFlash的ECC校验分为软件ECC校验和硬件ECC校验,由于该芯片自带OndieECC校验,因此我们对ondie ecc校验做个代码分析,以xilinx uboot为例,在上电过程中,完成对nandflash的初始化和Ondie ecc的校验。
Xilinx的启动主要为一下几个步骤:
1.根据器件的MIO[2…8]确定从那个设备启动
2.加载FSBL,FSBL主要完成以下几件事:
1.初始化PS
2.将bitstream写入PL
3.跳转到SSBL,即UBOOT阶段
start.s->cpu_init_crit->lowlevel_init->s_init->board_init_f->board_init_r->main_loop
nandflash的初始化处在board_init_r阶段,通过nand_init初始化nand flash芯片:
void nand_init(void)
{
#ifdef CONFIG_SYS_NAND_SELF_INIT
board_nand_init();
#else
int i;
for (i = 0; i < CONFIG_SYS_MAX_NAND_DEVICE; i++)
nand_init_chip(i);
#endif
printf("%lu MiB\n", total_nand_size / 1024);
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
/

* Select the chip in the board/cpu specific driver
*/
board_nand_select_device(nand_info[nand_curr_device].priv, nand_curr_device);
#endif
}
通过nand_init函数实现初始化,nand_init()调用board_nand_init函数,接着调用zynq_nand_init完成最终的nandflash的初始化,以及ECC校验,现在就ECC校验做详细说明,首先建立标记坏块的结构体,nand_oob_64表示每一页OOBSize为64Bytes,其中用来标记坏块的大小诶32Bytes,存放的位置为eccpos,偏移值为oobfree,
static struct nand_ecclayout ondie_nand_oob_64 = {
.eccbytes = 32,
.eccpos = {
8, 9, 10, 11, 12, 13, 14, 15,
24, 25, 26, 27, 28, 29, 30, 31,
40, 41, 42, 43, 44, 45, 46, 47,
56, 57, 58, 59, 60, 61, 62, 63
},
.oobfree = {
{ .offset = 4, .length = 4 },
{ .offset = 20, .length = 4 },
{ .offset = 36, .length = 4 },
{ .offset = 52, .length = 4 }
}
};

通过if (get_feature[0] & 0x08) {
debug("%s: OnDie ECC flash\n", func);
ondie_ecc_enabled = 1;
} else {
printf("%s: Unable to detect OnDie ECC\n", func);
}判断是否支持硬件ECC,这里是支持的,然后进入
if (ondie_ecc_enabled) {
/* bypass the controller ECC block /
ecc_cfg = readl(&zynq_nand_smc_base->emcr);
ecc_cfg &= ~0xc;
writel(ecc_cfg, &zynq_nand_smc_base->emcr);
/
The software ECC routines won’t work
* with the SMC controller
/
nand_chip->ecc.mode = NAND_ECC_HW;
nand_chip->ecc.strength = 1;
nand_chip->ecc.read_page = zynq_nand_read_page_raw_nooob;
nand_chip->ecc.read_subpage = zynq_nand_read_subpage_raw;
nand_chip->ecc.write_page = zynq_nand_write_page_raw;
nand_chip->ecc.read_page_raw = zynq_nand_read_page_raw;
nand_chip->ecc.write_page_raw = zynq_nand_write_page_raw;
nand_chip->ecc.read_oob = zynq_nand_read_oob;
nand_chip->ecc.write_oob = zynq_nand_write_oob;
nand_chip->ecc.size = mtd->writesize;
nand_chip->ecc.bytes = 0;
/
NAND with on-die ECC supports subpage reads /
nand_chip->options |= NAND_SUBPAGE_READ;
/
On-Die ECC spare bytes offset 8 is used for ECC codes /
if (ondie_ecc_enabled) {
nand_chip->ecc.layout = &ondie_nand_oob_64;//将结构体赋值给ecclayout
/
Use the BBT pattern descriptors */
nand_chip->bbt_td = &bbt_main_descr;
nand_chip->bbt_md = &bbt_mirror_descr;
}
}接着通过调用nand_scan_tail函数查询并记录本次的ECC校验结果

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值