From 01c6e6f1b0ed454b190ba8b6d22580f4f51e3b5b Mon Sep 17 00:00:00 2001 From: hxy Date: Thu, 16 Dec 2010 14:30:15 +0800 Subject: [PATCH] modified nand flash driver for new structure --- arch/arm/mach-rk29/include/mach/rk29_nand.h | 22 ++++++----- drivers/mtd/nand/rk29_nand.c | 42 ++++++++------------- 2 files changed, 27 insertions(+), 37 deletions(-) diff --git a/arch/arm/mach-rk29/include/mach/rk29_nand.h b/arch/arm/mach-rk29/include/mach/rk29_nand.h index 57f7277a69f5..d41e23153f5d 100644 --- a/arch/arm/mach-rk29/include/mach/rk29_nand.h +++ b/arch/arm/mach-rk29/include/mach/rk29_nand.h @@ -82,26 +82,28 @@ typedef volatile struct tagCHIP_IF }CHIP_IF, *pCHIP_IF; //NANDC Registers -typedef volatile struct tagNANDC +typedef volatile struct tagNANDC { volatile uint32_t FMCTL; volatile uint32_t FMWAIT; volatile uint32_t FLCTL; volatile uint32_t BCHCTL; - volatile uint32_t BCHST; - volatile uint32_t RESERVED1[(0x200-0x14)/4]; //FLR + volatile uint32_t MTRANS_CFG; + volatile uint32_t MTRANS_SADDR0; + volatile uint32_t MTRANS_SADDR1; + volatile uint32_t MTRANS_STAT; + + volatile uint32_t BCHST[8]; + volatile uint32_t FLR1[(0x160-0x40)/4]; + volatile uint32_t NANDC_VER; + volatile uint32_t FLR2[(0x200-0x164)/4]; volatile uint32_t spare[0x200/4]; - volatile uint32_t FMCTL1; - volatile uint32_t FMWAIT1; - volatile uint32_t FLCTL1; - volatile uint32_t BCHCTL1; - volatile uint32_t BCHST1; - volatile uint32_t RESERVED2[(0x200-0x14)/4]; - volatile uint32_t RESERVED3[0x200/4]; + volatile uint32_t RESERVED2[0x400/4]; volatile CHIP_IF chip[8]; volatile uint32_t buf[0x800/4]; }NANDC, *pNANDC; + struct rk29_nand_flash { const struct rk29_nand_timing *timing; /* NAND Flash timing */ const struct rk29_nand_cmdset *cmdset; diff --git a/drivers/mtd/nand/rk29_nand.c b/drivers/mtd/nand/rk29_nand.c index 6d2beeee00e8..222d2d8ef8cb 100644 --- a/drivers/mtd/nand/rk29_nand.c +++ b/drivers/mtd/nand/rk29_nand.c @@ -137,7 +137,7 @@ static void rk29_nand_wait_bchdone(struct mtd_info *mtd, uint32_t timeout) { timeout--; udelay(1); - if(pRK29NC->BCHST &(1<<1)) + if(pRK29NC->BCHST[0] &(1<<1)) break; } @@ -324,15 +324,13 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_READID: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); pRK29NC ->chip[master->cs].addr = 0x0; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,READ_BUSY_COUNT); break; case NAND_CMD_READ0: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( column>= 0 ) { pRK29NC ->chip[master->cs].addr = column & 0xff; @@ -345,11 +343,10 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, pRK29NC ->chip[master->cs].addr = (page_addr >> 8) & 0xFF; pRK29NC ->chip[master->cs].addr = (page_addr >> 16) & 0xff; } - rk29_nand_wait_ready(mtd); if( mtd->writesize > 512) - pRK29NC ->chip[0].cmd = NAND_CMD_READSTART; + pRK29NC ->chip[master->cs].cmd = NAND_CMD_READSTART; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,READ_BUSY_COUNT); break; @@ -366,7 +363,6 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( mtd->writesize >512 ) { if ( column>= 0 ) @@ -386,8 +382,7 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, { pRK29NC ->chip[master->cs].addr = column; } - rk29_nand_wait_ready(mtd); - + udelay(1); rk29_nand_wait_busy(mtd,READ_BUSY_COUNT); @@ -396,11 +391,10 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_PAGEPROG: pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,PROGRAM_BUSY_COUNT); pRK29NC ->chip[master->cs].cmd = NAND_CMD_STATUS; - rk29_nand_wait_ready(mtd); status = pRK29NC ->chip[master->cs].data; if(status&0x1) @@ -414,7 +408,6 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->BCHCTL = 0x0; pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( page_addr>=0 ) { pRK29NC ->chip[master->cs].addr = page_addr & 0xff; @@ -426,10 +419,8 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_ERASE2: pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); rk29_nand_wait_busy(mtd,ERASE_BUSY_COUNT); pRK29NC ->chip[master->cs].cmd = NAND_CMD_STATUS; - rk29_nand_wait_ready(mtd); status = pRK29NC ->chip[master->cs].data; if(status&0x1) @@ -442,7 +433,6 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_SEQIN: pRK29NC ->FMCTL |= FMC_WP; //½â³ýд±£»¤ pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); if ( column>= 0 ) { pRK29NC ->chip[master->cs].addr = column; @@ -461,19 +451,17 @@ static void rk29_nand_cmdfunc(struct mtd_info *mtd, unsigned command,int column, case NAND_CMD_STATUS: pRK29NC ->BCHCTL = 0x0; pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); break; case NAND_CMD_RESET: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); + udelay(1); rk29_nand_wait_busy(mtd,RESET_BUSY_COUNT); break; /* This applies to read commands */ default: pRK29NC ->chip[master->cs].cmd = command; - rk29_nand_wait_ready(mtd); break; } @@ -521,7 +509,7 @@ int rk29_nand_calculate_ecc(struct mtd_info *mtd,const uint8_t *dat,uint8_t *ecc pNANDC pRK29NC= (pNANDC)(master->regs); // hw correct data - if( pRK29NC->BCHST & (1<<2) ) + if( pRK29NC->BCHST[0] & (1<<2) ) { DEBUG(MTD_DEBUG_LEVEL0, "rk2818 nand :hw ecc uncorrectable error\n"); @@ -561,7 +549,7 @@ int rk29_nand_calculate_ecc(struct mtd_info *mtd,const uint8_t *dat,uint8_t *ecc pRK29NC ->BCHCTL = BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ; wait_op_done(mtd,TROP_US_DELAY,0); - //rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; + rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; memcpy(buf+i*0x400,(u_char *)(pRK29NC->buf),0x400); // only use nandc sram0 } @@ -597,16 +585,16 @@ void rk29_nand_write_page(struct mtd_info *mtd,struct nand_chip *chip,const uin for(i=0;iwritesize/0x400;i++) { + pRK29NC ->BCHCTL = BCH_WR|BCH_RST; memcpy((u_char *)(pRK29NC->buf),(buf+i*0x400),0x400); // only use nandc sram0 if(i==0) memcpy((u_char *)(pRK29NC->spare),(u_char *)(chip->oob_poi + chip->ops.ooboffs),4); - pRK29NC ->BCHCTL = BCH_WR|BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_RDN|FL_BYPASS|FL_START; wait_op_done(mtd,TROP_US_DELAY,0); } - pRK29NC ->chip[0].cmd = NAND_CMD_PAGEPROG; + pRK29NC ->chip[chipnr].cmd = NAND_CMD_PAGEPROG; @@ -655,7 +643,7 @@ int rk29_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip, int page, i pRK29NC ->BCHCTL = BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ; wait_op_done(mtd,TROP_US_DELAY,0); - //rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; + rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; if(i==0) memcpy((u_char *)(chip->oob_poi+ chip->ops.ooboffs),(u_char *)(pRK29NC->spare),4); } @@ -698,7 +686,7 @@ int rk29_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip, uint8_ pRK29NC ->BCHCTL = BCH_RST; pRK29NC ->FLCTL = (0<<4)|FL_COR_EN|(0x1<<5)|FL_BYPASS|FL_START ; wait_op_done(mtd,TROP_US_DELAY,0); - //rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; + rk29_nand_wait_bchdone(mtd,TROP_US_DELAY) ; memcpy(buf+i*0x400,(u_char *)(pRK29NC->buf),0x400); // only use nandc sram0 if(i==0) memcpy((u_char *)(chip->oob_poi+ chip->ops.ooboffs),(u_char *)(pRK29NC->spare),4); @@ -725,12 +713,12 @@ static int rk29_nand_setrate(struct rk29_nand_mtd *info) // some nand flashs have not timing id and almost all nand flash access time is 25ns, so need to fix accesstime to 40 ns - accesstime = 40; + accesstime = 50; info->clk_rate = clkrate; clkrate /= 1000000; /* turn clock into MHz for ease of use */ - if(clkrate>0 && clkrate<=250) + if(clkrate>0 && clkrate<=400) ns= 1000/clkrate; // ns else return -1; -- 2.34.1