X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmtd%2Fnand%2Ffsl_elbc_nand.c;h=795209788ba038d8333e6df1697d0c35764672c7;hb=3be2bdf5dc69b3142c1162a59bc67191c9077567;hp=834a8a64983f35d01abdb1383cd928fbb155b6ff;hpb=dfe161032d007e4901064ab36b58f054126b1f35;p=u-boot diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 834a8a6498..795209788b 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -5,19 +5,7 @@ * Authors: Nick Spence , * Scott Wood * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -640,9 +628,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 +643,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 +735,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 +744,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 +757,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 +790,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;