[PATCH] mtd: fsl_upm: Enable software BCH ECC support
Aaron Sierra
asierra at xes-inc.com
Tue Aug 4 10:52:54 PDT 2015
This patch preserves the default software ECC mode while adding the
ability to use BCH ECC (as required for larger NAND devices).
The BCH-required strength and step size values are pulled from the
device-tree by nand_scan_ident(), so we replace nand_scan() with
explicit calls to nand_scan_ident() and nand_scan_tail() in order
to sanity check ECC properties from the device-tree.
Tested-by: Ryan Schaefer <rschaefer at xes-inc.com>
Signed-off-by: Jordan Friendshuh <jfriendshuh at xes-inc.com>
Signed-off-by: Aaron Sierra <asierra at xes-inc.com>
---
.../devicetree/bindings/mtd/fsl-upm-nand.txt | 32 ++++++++++++++++++++
drivers/mtd/nand/fsl_upm.c | 35 +++++++++++++++++++++-
2 files changed, 66 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt
index fce4894..3643ee1 100644
--- a/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/fsl-upm-nand.txt
@@ -18,6 +18,9 @@ Optional properties:
- chip-delay : chip dependent delay for transferring data from array to
read registers (tR). Required if property "gpios" is not used
(R/B# pins not connected).
+- nand-ecc-mode : as defined by nand.txt ("soft" and "soft_bch", only).
+- nand-ecc-strength : as defined by nand.txt.
+- nand-ecc-step-size : as defined by nand.txt.
Each flash chip described may optionally contain additional sub-nodes
describing partitions of the address space. See partition.txt for more
@@ -65,3 +68,32 @@ upm at 3,0 {
};
};
};
+
+/*
+ * Micron MT29F32G08AFABA (M62B)
+ * 32 Gb (4 GiB), 2 chipselect
+ */
+upm at 2,0 {
+ #address-cells = <0>;
+ #size-cells = <0>;
+ compatible = "fsl,upm-nand";
+ reg = <2 0x0 0x80000>;
+ fsl,upm-addr-line-cs-offsets = <0x0 0x10000>;
+ fsl,upm-addr-offset = <0x10>;
+ fsl,upm-cmd-offset = <0x08>;
+ fsl,upm-wait-flags = <0x1>;
+ chip-delay = <50>;
+
+ nand at 0 {
+ #address-cells = <1>;
+ #size-cells = <2>;
+ nand-ecc-mode = "soft_bch";
+ nand-ecc-strength = <4>;
+ nand-ecc-step-size = <512>;
+
+ partition at 0 {
+ label = "NAND filesystem";
+ reg = <0x0 0x1 0x00000000>;
+ };
+ };
+};
diff --git a/drivers/mtd/nand/fsl_upm.c b/drivers/mtd/nand/fsl_upm.c
index 72755d7..0982d7a 100644
--- a/drivers/mtd/nand/fsl_upm.c
+++ b/drivers/mtd/nand/fsl_upm.c
@@ -182,6 +182,7 @@ static int fun_chip_init(struct fsl_upm_nand *fun,
if (!flash_np)
return -ENODEV;
+ fun->chip.dn = flash_np;
fun->mtd.name = kasprintf(GFP_KERNEL, "0x%llx.%s", (u64)io_res->start,
flash_np->name);
if (!fun->mtd.name) {
@@ -189,7 +190,39 @@ static int fun_chip_init(struct fsl_upm_nand *fun,
goto err;
}
- ret = nand_scan(&fun->mtd, fun->mchip_count);
+ ret = nand_scan_ident(&fun->mtd, fun->mchip_count, NULL);
+ if (ret)
+ goto err;
+
+ switch (fun->chip.ecc.mode) {
+ case NAND_ECC_NONE:
+ fun->chip.ecc.mode = NAND_ECC_SOFT;
+ break;
+ case NAND_ECC_SOFT:
+ if (fun->chip.ecc.strength && fun->chip.ecc.strength != 1)
+ dev_warn(fun->dev, "Ignoring %d-bit software ECC\n",
+ fun->chip.ecc.strength);
+ if (fun->chip.ecc.size &&
+ (fun->chip.ecc.size != 256) &&
+ (fun->chip.ecc.size != 512)) {
+ dev_err(fun->dev, "Invalid software ECC step: %d\n",
+ fun->chip.ecc.size);
+ goto err;
+ }
+ break;
+ case NAND_ECC_SOFT_BCH:
+ if (fun->chip.ecc.strength < 2) {
+ dev_err(fun->dev, "Invalid BCH ECC strength: %d\n",
+ fun->chip.ecc.strength);
+ goto err;
+ }
+ break;
+ default:
+ dev_err(fun->dev, "ECC mode unsupported");
+ goto err;
+ }
+
+ ret = nand_scan_tail(&fun->mtd);
if (ret)
goto err;
--
1.9.1
More information about the linux-mtd
mailing list