From: Stefan Agner <[email protected]>

Add support for specified ECC strength/size using device tree
properties nand-ecc-strength/nand-ecc-step-size.

This aligns behavior with the mainline driver, such that:
- If fsl,use-minimal-ecc is requested it will use data from
  data sheet/ONFI. If this is not available the driver will fail.
- If nand-ecc-strength/nand-ecc-step-size are specified those
  value will be used.
- By default maximum possible ECC strength is used

Signed-off-by: Stefan Agner <[email protected]>
---

 drivers/mtd/nand/mxs_nand.c | 44 +++++++++++++++++++++++++------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/mxs_nand.c b/drivers/mtd/nand/mxs_nand.c
index 8c3f4f1871..746444d3fd 100644
--- a/drivers/mtd/nand/mxs_nand.c
+++ b/drivers/mtd/nand/mxs_nand.c
@@ -162,15 +162,14 @@ static inline int mxs_nand_calc_mark_offset(struct 
bch_geometry *geo,
 }
 
 static inline int mxs_nand_calc_ecc_layout_by_info(struct bch_geometry *geo,
-                                                  struct mtd_info *mtd)
+                                                  struct mtd_info *mtd,
+                                                  unsigned int ecc_strength,
+                                                  unsigned int ecc_step)
 {
        struct nand_chip *chip = mtd_to_nand(mtd);
        struct mxs_nand_info *nand_info = nand_get_controller_data(chip);
 
-       if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
-               return -ENOTSUPP;
-
-       switch (chip->ecc_step_ds) {
+       switch (ecc_step) {
        case SZ_512:
                geo->gf_len = 13;
                break;
@@ -181,8 +180,8 @@ static inline int mxs_nand_calc_ecc_layout_by_info(struct 
bch_geometry *geo,
                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);
 
        /* Keep the C >= O */
        if (geo->ecc_chunk_size < mtd->oobsize)
@@ -965,6 +964,28 @@ static int mxs_nand_block_bad(struct mtd_info *mtd, loff_t 
ofs)
        return 0;
 }
 
+static int mxs_nand_set_geometry(struct mtd_info *mtd, struct bch_geometry 
*geo)
+{
+       struct nand_chip *chip = mtd_to_nand(mtd);
+       struct nand_chip *nand = mtd_to_nand(mtd);
+       struct mxs_nand_info *nand_info = nand_get_controller_data(nand);
+
+       if (chip->ecc.strength > 0 && chip->ecc.size > 0)
+               return mxs_nand_calc_ecc_layout_by_info(geo, mtd,
+                               chip->ecc.strength, chip->ecc.size);
+
+       if (nand_info->use_minimum_ecc ||
+               mxs_nand_calc_ecc_layout(geo, mtd)) {
+               if (!(chip->ecc_strength_ds > 0 && chip->ecc_step_ds > 0))
+                       return -EINVAL;
+
+               return mxs_nand_calc_ecc_layout_by_info(geo, mtd,
+                               chip->ecc_strength_ds, chip->ecc_step_ds);
+       }
+
+       return 0;
+}
+
 /*
  * At this point, the physical NAND Flash chips have been identified and
  * counted, so we know the physical geometry. This enables us to make some
@@ -981,14 +1002,9 @@ static int mxs_nand_setup_ecc(struct mtd_info *mtd)
        struct bch_geometry *geo = &nand_info->bch_geometry;
        struct mxs_bch_regs *bch_regs = nand_info->bch_regs;
        uint32_t tmp;
-       int ret = -ENOTSUPP;
-
-       if (nand_info->use_minimum_ecc)
-               ret = mxs_nand_calc_ecc_layout_by_info(geo, mtd);
-
-       if (ret == -ENOTSUPP)
-               ret = mxs_nand_calc_ecc_layout(geo, mtd);
+       int ret;
 
+       ret = mxs_nand_set_geometry(mtd, geo);
        if (ret)
                return ret;
 
-- 
2.17.0

_______________________________________________
U-Boot mailing list
[email protected]
https://lists.denx.de/listinfo/u-boot

Reply via email to