Message ID | 20220412025246.24269-2-han.xu@nxp.com |
---|---|
State | Accepted |
Headers | show |
Series | Refactor bch settings and support large oob NAND | expand |
On Tue, 2022-04-12 at 02:52:42 UTC, Han Xu wrote: > The code change refactor the bch geometry setting function, which > doesn't change the default behavior, while user may choose to use chips > required minimum ecc strength by DT flag "fsl,use-minimum-ecc". > > The default way to set bch geometry need to set the data chunk > size(step_size) larger than oob size to make sure BBM locates in data > chunk, then set the maximum ecc strength oob can hold. It always use > unbalanced ECC layout, which ecc0 will cover both meta and data0 chunk. > But the default bch setting is deprecated for large oobsize NAND > (oobsize >1KB), so in the patch set, there is a split commit that > introduces a new way to set bch geometry for large oob size NAND. > > For all other cases,set the bch geometry by chip required strength and > step size, which uses the minimum ecc strength chip required. It can be > explicitly enabled by DT flag "fsl,use-minimum-ecc", but need to be > en/disabled in both u-boot and kernel at the same time. > > Signed-off-by: Han Xu <han.xu@nxp.com> > Tested-by: Sean Nyekjaer <sean@geanix.com> Applied to https://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux.git nand/next, thanks. Miquel
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index 44b14c9dc9a7..66ebd569858d 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -514,24 +514,32 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) static int common_nfc_set_geometry(struct gpmi_nand_data *this) { struct nand_chip *chip = &this->nand; + struct mtd_info *mtd = nand_to_mtd(&this->nand); const struct nand_ecc_props *requirements = nanddev_get_ecc_requirements(&chip->base); + bool use_minimun_ecc; + int err; - if (chip->ecc.strength > 0 && chip->ecc.size > 0) - return set_geometry_by_ecc_info(this, chip->ecc.strength, - chip->ecc.size); - - if ((of_property_read_bool(this->dev->of_node, "fsl,use-minimum-ecc")) - || legacy_set_geometry(this)) { - if (!(requirements->strength > 0 && requirements->step_size > 0)) - return -EINVAL; + use_minimun_ecc = of_property_read_bool(this->dev->of_node, + "fsl,use-minimum-ecc"); - return set_geometry_by_ecc_info(this, - requirements->strength, - requirements->step_size); + /* use legacy bch geometry settings by default*/ + if ((!use_minimun_ecc && mtd->oobsize < 1024) || + !(requirements->strength > 0 && requirements->step_size > 0)) { + dev_dbg(this->dev, "use legacy bch geometry\n"); + err = legacy_set_geometry(this); + if (!err) + return 0; } - return 0; + /* otherwise use the minimum ecc nand chip required */ + dev_dbg(this->dev, "use minimum ecc bch geometry\n"); + err = set_geometry_by_ecc_info(this, requirements->strength, + requirements->step_size); + if (err) + dev_err(this->dev, "none of the bch geometry setting works\n"); + + return err; } /* Configures the geometry for BCH. */