diff options
Diffstat (limited to 'drivers/mtd/nand/fsl_elbc_nand.c')
| -rw-r--r-- | drivers/mtd/nand/fsl_elbc_nand.c | 56 | 
1 files changed, 31 insertions, 25 deletions
| diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 834a8a649..0fa776ae9 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -640,9 +640,8 @@ static int fsl_elbc_wait(struct mtd_info *mtd, struct nand_chip *chip)  	return fsl_elbc_read_byte(mtd);  } -static int fsl_elbc_read_page(struct mtd_info *mtd, -			      struct nand_chip *chip, -			      uint8_t *buf, int page) +static int fsl_elbc_read_page(struct mtd_info *mtd, struct nand_chip *chip, +			      uint8_t *buf, int oob_required, int page)  {  	fsl_elbc_read_buf(mtd, buf, mtd->writesize);  	fsl_elbc_read_buf(mtd, chip->oob_poi, mtd->oobsize); @@ -656,12 +655,13 @@ static int fsl_elbc_read_page(struct mtd_info *mtd,  /* ECC will be calculated automatically, and errors will be detected in   * waitfunc.   */ -static void fsl_elbc_write_page(struct mtd_info *mtd, -				struct nand_chip *chip, -				const uint8_t *buf) +static int fsl_elbc_write_page(struct mtd_info *mtd, struct nand_chip *chip, +				const uint8_t *buf, int oob_required)  {  	fsl_elbc_write_buf(mtd, buf, mtd->writesize);  	fsl_elbc_write_buf(mtd, chip->oob_poi, mtd->oobsize); + +	return 0;  }  static struct fsl_elbc_ctrl *elbc_ctrl; @@ -747,8 +747,8 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)  	nand->bbt_md = &bbt_mirror_descr;    	/* set up nand options */ -	nand->options = NAND_NO_READRDY | NAND_NO_AUTOINCR | -			NAND_USE_FLASH_BBT | NAND_NO_SUBPAGE_WRITE; +	nand->options = NAND_NO_SUBPAGE_WRITE; +	nand->bbt_options = NAND_BBT_USE_FLASH;  	nand->controller = &elbc_ctrl->controller;  	nand->priv = priv; @@ -756,20 +756,8 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)  	nand->ecc.read_page = fsl_elbc_read_page;  	nand->ecc.write_page = fsl_elbc_write_page; -#ifdef CONFIG_FSL_ELBC_FMR -	priv->fmr = CONFIG_FSL_ELBC_FMR; -#else  	priv->fmr = (15 << FMR_CWTO_SHIFT) | (2 << FMR_AL_SHIFT); -	/* -	 * Hardware expects small page has ECCM0, large page has ECCM1 -	 * when booting from NAND.  Board config can override if not -	 * booting from NAND. -	 */ -	if (or & OR_FCM_PGS) -		priv->fmr |= FMR_ECCM; -#endif -  	/* If CS Base Register selects full hardware ECC then use it */  	if ((br & BR_DECC) == BR_DECC_CHK_GEN) {  		nand->ecc.mode = NAND_ECC_HW; @@ -781,16 +769,32 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)  		nand->ecc.size = 512;  		nand->ecc.bytes = 3;  		nand->ecc.steps = 1; +		nand->ecc.strength = 1;  	} else {  		/* otherwise fall back to default software ECC */  		nand->ecc.mode = NAND_ECC_SOFT;  	} +	ret = nand_scan_ident(mtd, 1, NULL); +	if (ret) +		return ret; +  	/* Large-page-specific setup */ -	if (or & OR_FCM_PGS) { +	if (mtd->writesize == 2048) { +		setbits_be32(&elbc_ctrl->regs->bank[priv->bank].or, +			     OR_FCM_PGS); +		in_be32(&elbc_ctrl->regs->bank[priv->bank].or); +  		priv->page_size = 1;  		nand->badblock_pattern = &largepage_memorybased; +		/* +		 * Hardware expects small page has ECCM0, large page has +		 * ECCM1 when booting from NAND, and we follow that even +		 * when not booting from NAND. +		 */ +		priv->fmr |= FMR_ECCM; +  		/* adjust ecc setup if needed */  		if ((br & BR_DECC) == BR_DECC_CHK_GEN) {  			nand->ecc.steps = 4; @@ -798,12 +802,14 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr)  					   &fsl_elbc_oob_lp_eccm1 :  					   &fsl_elbc_oob_lp_eccm0;  		} +	} else if (mtd->writesize == 512) { +		clrbits_be32(&elbc_ctrl->regs->bank[priv->bank].or, +			     OR_FCM_PGS); +		in_be32(&elbc_ctrl->regs->bank[priv->bank].or); +	} else { +		return -ENODEV;  	} -	ret = nand_scan_ident(mtd, 1, NULL); -	if (ret) -		return ret; -  	ret = nand_scan_tail(mtd);  	if (ret)  		return ret; |