From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Tue, 4 Aug 2015 12:52:54 -0500 (CDT) From: Aaron Sierra To: Brian Norris , David Woodhouse , Ezequiel Garcia Cc: linux-mtd@lists.infradead.org Message-ID: <288216793.189179.1438710774869.JavaMail.zimbra@xes-inc.com> In-Reply-To: <447095612.147126.1421278909058.JavaMail.zimbra@xes-inc.com> Subject: [PATCH] mtd: fsl_upm: Enable software BCH ECC support MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , 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 Signed-off-by: Jordan Friendshuh Signed-off-by: Aaron Sierra --- .../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@3,0 { }; }; }; + +/* + * Micron MT29F32G08AFABA (M62B) + * 32 Gb (4 GiB), 2 chipselect + */ +upm@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@0 { + #address-cells = <1>; + #size-cells = <2>; + nand-ecc-mode = "soft_bch"; + nand-ecc-strength = <4>; + nand-ecc-step-size = <512>; + + partition@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