OSDN Git Service

mtd: rawnand: gpmi: add support for specific ECC strength
authorStefan Agner <stefan@agner.ch>
Sun, 4 Mar 2018 20:06:01 +0000 (21:06 +0100)
committerBoris Brezillon <boris.brezillon@bootlin.com>
Sun, 29 Apr 2018 06:56:40 +0000 (08:56 +0200)
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>
drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c

index c2597c8..abd5146 100644 (file)
@@ -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;
 }