S5PV210(TQ210)学习笔记——Nand驱动之HWECC
时间:11-28
来源:互联网
点击:
前几天匆忙间发了一篇关于S5PV210的8位HWECC驱动的文章,但是后来发现存在严重的Bug,就将原来那篇文章删除了,这里先说声抱歉,但是,HWECC能有效的节省CPU占用量,我仔细调试了S5PV210的HWECC部分,现在刚调好1位的HWECC,为了表示误发原来那篇文章的歉意,现在将代码放在这里,与大家分享:
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #defineNFCONT_MECCLOCK(1<7)
- #defineNFCONT_SECCLOCK(1<6)
- #defineNFCONT_INITMECC(1<5)
- #defineNFCONT_INITSECC(1<4)
- #defineNFCONT_INITECC(NFCONT_INITMECC|NFCONT_INITSECC)
- structs5p_nand_regs{
- unsignedlongnfconf;
- unsignedlongnfcont;
- unsignedlongnfcmmd;
- unsignedlongnfaddr;
- unsignedlongnfdata;
- unsignedlongnfmeccd0;
- unsignedlongnfmeccd1;
- unsignedlongnfseccd;
- unsignedlongnfsblk;
- unsignedlongnfeblk;
- unsignedlongnfstat;
- unsignedlongnfeccerr0;
- unsignedlongnfeccerr1;
- unsignedlongnfmecc0;
- unsignedlongnfmecc1;
- unsignedlongnfsecc;
- unsignedlongnfmlcbitpt;
- };
- staticvolatilestructs5p_nand_regs*s5p_nand_regs;
- staticstructnand_chip*nand_chip;
- staticstructmtd_info*s5p_mtd_info;
- staticstructclk*s5p_nand_clk;
- staticinteccmode;
- staticstructnand_ecclayouts5p_nand_oob_64={
- .eccbytes=16,
- .eccpos={
- 40,41,42,43,44,45,46,47,
- 48,49,50,51,52,53,54,55
- },
- .oobfree={
- {
- .offset=2,
- .length=38
- }
- }
- };
- staticstructmtd_partitions5p_nand_partions[]={
- [0]={
- .name="bootloader",
- .offset=0,
- .size=SZ_1M,
- },
- [1]={
- .name="kernel",
- .offset=MTDPART_OFS_APPEND,
- .size=5*SZ_1M,
- },
- [2]={
- .name="rootfs",
- .offset=MTDPART_OFS_APPEND,
- .size=MTDPART_SIZ_FULL,
- },
- };
- staticvoids5p_nand_cmd_ctrl(structmtd_info*mtd,intcmd,unsignedintctrl)
- {
- if(ctrl&NAND_CTRL_CHANGE){
- if(ctrl&NAND_NCE){
- if(cmd!=NAND_CMD_NONE){
- s5p_nand_regs->nfcont&=~(1<1);
- }
- }else{
- s5p_nand_regs->nfcont|=(1<1);
- }
- }
- if(cmd!=NAND_CMD_NONE){
- if(ctrl&NAND_CLE)
- s5p_nand_regs->nfcmmd=cmd;
- elseif(ctrl&NAND_ALE)
- s5p_nand_regs->nfaddr=cmd;
- }
- }
- staticints5p_nand_ready(structmtd_info*mtd){
- return(s5p_nand_regs->nfstat&0x1);
- }
- staticvoids5p_ecc_hwctl(structmtd_info*mtd,intmode){
- eccmode=mode;
- s5p_nand_regs->nfconf&=~(0x3<23);
- /*InitmainECC&unlock*/
- s5p_nand_regs->nfcont|=NFCONT_INITMECC;
- s5p_nand_regs->nfcont&=~NFCONT_MECCLOCK;
- }
- staticints5p_ecc_calculate(structmtd_info*mtd,constuint8_t*dat,
- uint8_t*ecc_code){
- unsignedlongnfmecc0=s5p_nand_regs->nfmecc0;
- /*Lock*/
- s5p_nand_regs->nfcont|=NFCONT_MECCLOCK;
- ecc_code[0]=(nfmecc0)&0xff;
- ecc_code[1]=(nfmecc0>>8)&0xff;
- ecc_code[2]=(nfmecc0>>16)&0xff;
- ecc_code[3]=(nfmecc0>>24)&0xff;
- return0;
- }
- staticints5p_ecc_correct(structmtd_info*mtd,uint8_t*dat,uint8_t*read_ecc,uint8_t*calc_ecc){
- unsignednfmeccd0,nfmeccd1;
- unsignedlongnfeccerr0;
- nfmeccd0=(read_ecc[1]<16)|read_ecc[0];
- nfmeccd1=(read_ecc[3]<16)|read_ecc[2];
- s5p_nand_regs->nfmeccd0=nfmeccd0;
- s5p_nand_regs->nfmeccd1=nfmeccd1;
- nfeccerr0=s5p_nand_regs->nfeccerr0;
- switch(nfeccerr0&0x3){
- case0:
- return0;
- case1:
- printk("s5p-nand:detectedonebiterror");
- dat[(nfeccerr0>>7)&0x7ff]^=1<((nfeccerr0>>4)&0x3);
- return1;
- case2:
- case3:
- printk("s5p-nand:detecteduncorrectederror");
- return3;
- default:
- return-EIO;
- }
- }
- staticints5p_nand_read_page(structmtd_info*mtd,structnand_chip*chip,
- uint8_t*buf,intoob_required,intpage)
- {
- inti,stat,eccsize=chip->ecc.size;
- inteccbytes=chip->ecc.bytes;
- inteccsteps=chip->ecc.steps;
- intsecc_start=mtd->oobsize-eccbytes;
- intcol=0;
- uint8_t*p=buf;
- uint32_t*mecc_pos=chip->ecc.layout->eccpos;
- uint8_t*ecc_calc=chip->buffers->ecccalc;
- col=mtd->writesize;
- chip->cmdfunc(mtd,NAND_CMD_RNDOUT,col,-1);
- /*sparearea*/
- chip->ecc.hwctl(mtd,NAND_ECC_READ);
- chip->read_buf(mtd,chip->oob_poi,secc_start);
- chip->ecc.calculate(mtd,p,&ecc_calc[chip->ecc.total]);
- chip->read_buf(mtd,chip->oob_poi+secc_start,eccbytes);
- col=0;
- /*mainarea*/
- for(i=0;eccsteps;eccsteps--,i+=eccbytes,p+=eccsize){
- chip->cmdfunc(mtd,NAND_CMD_RNDOUT,col,-1);
- chip->ecc.hwctl(mtd,NAND_ECC_READ);
- chip->read_buf(mtd,p,eccsize);
- chip->ecc.calculate(mtd,p,&ecc_calc[i]);
- stat=chip->ecc.correct(mtd,p,chip->stat=chip
S5PV210Nand驱动HWEC 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
