From 98d9d92359956a3d53eaee70c08d40f06828fa87 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Tue, 26 Feb 2013 13:00:50 +0000 Subject: [PATCH] nand/fsl_elbc: detect page size at runtime This avoids needing a separate U-Boot config when some revisions of a board have small-page NAND and other revisions have large-page NAND (except for NAND SPL targets). CONFIG_FSL_ELBC_FMR is removed -- it was never used nor documented, and it gets in the way of this change. Signed-off-by: Scott Wood --- drivers/mtd/nand/fsl_elbc_nand.c | 39 ++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index 834a8a6498..fb34d129b1 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -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; @@ -786,11 +774,26 @@ static int fsl_elbc_chip_init(int devnum, u8 *addr) 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 +801,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; -- 2.25.1