diff options
author | Stefan Agner <stefan@agner.ch> | 2018-03-04 21:06:01 +0100 |
---|---|---|
committer | Boris Brezillon <boris.brezillon@bootlin.com> | 2018-04-29 08:56:40 +0200 |
commit | 6bf6ec522e050359b92600f7f820c32181615f87 (patch) | |
tree | bcb2eea126167d683ceff24c6ea52eeea9cd6051 /drivers | |
parent | 69fb4ca07c724a990c78416b90f0ea486ddcaf34 (diff) |
mtd: rawnand: gpmi: add support for specific ECC strength
Add support for specified ECC strength/size using device tree
properties nand-ecc-strength/nand-ecc-step-size.
Signed-off-by: Stefan Agner <stefan@agner.ch>
Acked-by: Han Xu <han.xu@nxp.com>
Signed-off-by: Boris Brezillon <boris.brezillon@bootlin.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c | 30 |
1 files changed, 20 insertions, 10 deletions
diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c index c2597c8107a0..abd5146931fa 100644 --- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c +++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c @@ -198,17 +198,16 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this) * * We may have available oob space in this case. */ -static int set_geometry_by_ecc_info(struct gpmi_nand_data *this) +static int set_geometry_by_ecc_info(struct gpmi_nand_data *this, + unsigned int ecc_strength, + unsigned int ecc_step) { struct bch_geometry *geo = &this->bch_geometry; struct nand_chip *chip = &this->nand; struct mtd_info *mtd = nand_to_mtd(chip); unsigned int block_mark_bit_offset; - if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) - return -EINVAL; - - switch (chip->ecc_step_ds) { + switch (ecc_step) { case SZ_512: geo->gf_len = 13; break; @@ -221,8 +220,8 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this) chip->ecc_strength_ds, chip->ecc_step_ds); return -EINVAL; } - geo->ecc_chunk_size = chip->ecc_step_ds; - geo->ecc_strength = round_up(chip->ecc_strength_ds, 2); + geo->ecc_chunk_size = ecc_step; + geo->ecc_strength = round_up(ecc_strength, 2); if (!gpmi_check_ecc(this)) return -EINVAL; @@ -230,7 +229,7 @@ static int set_geometry_by_ecc_info(struct gpmi_nand_data *this) if (geo->ecc_chunk_size < mtd->oobsize) { dev_err(this->dev, "unsupported nand chip. ecc size: %d, oob size : %d\n", - chip->ecc_step_ds, mtd->oobsize); + ecc_step, mtd->oobsize); return -EINVAL; } @@ -423,9 +422,20 @@ static int legacy_set_geometry(struct gpmi_nand_data *this) int common_nfc_set_geometry(struct gpmi_nand_data *this) { + struct nand_chip *chip = &this->nand; + + 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)) - return set_geometry_by_ecc_info(this); + || legacy_set_geometry(this)) { + if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0)) + return -EINVAL; + + return set_geometry_by_ecc_info(this, chip->ecc_strength_ds, + chip->ecc_step_ds); + } return 0; } |