aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrian Norris <computersforpeace@gmail.com>2016-04-26 01:53:55 -0400
committerBoris Brezillon <boris.brezillon@free-electrons.com>2016-05-05 17:55:15 -0400
commit666b65683dad9aa90efaa4aad24ef3710101e3aa (patch)
treec784f713f3cbf7c94aede09cf6008666ed020060
parentbd2e778c9ee361c23ccb2b10591712e129d97893 (diff)
mtd: brcmnand: respect ECC algorithm set by NAND subsystem
This is more obvious than guessing based on ECC strength. It allows using NAND on devices with BCH-1 (e.g. D-Link DIR-885L). This maintains DT backward compatibility by defaulting to Hamming if a 1-bit ECC algorithm is specified without a corresponding algorithm selection. i.e., to use BCH-1, you must specify: nand-ecc-strength = <1>; nand-ecc-step-size = <512>; nand-ecc-algo = "bch"; Also adds a check to ensure we haven't allowed someone to get by with SW ECC. If we want to support SW ECC, we need to refactor some other pieces of this driver. Signed-off-by: Brian Norris <computersforpeace@gmail.com> Tested-by: Rafał Miłecki <zajec5@gmail.com> Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
-rw-r--r--drivers/mtd/nand/brcmnand/brcmnand.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c
index c3331ffcaffd..b76ad7c0144f 100644
--- a/drivers/mtd/nand/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/brcmnand/brcmnand.c
@@ -1925,9 +1925,31 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
1925 cfg->col_adr_bytes = 2; 1925 cfg->col_adr_bytes = 2;
1926 cfg->blk_adr_bytes = get_blk_adr_bytes(mtd->size, mtd->writesize); 1926 cfg->blk_adr_bytes = get_blk_adr_bytes(mtd->size, mtd->writesize);
1927 1927
1928 if (chip->ecc.mode != NAND_ECC_HW) {
1929 dev_err(ctrl->dev, "only HW ECC supported; selected: %d\n",
1930 chip->ecc.mode);
1931 return -EINVAL;
1932 }
1933
1934 if (chip->ecc.algo == NAND_ECC_UNKNOWN) {
1935 if (chip->ecc.strength == 1 && chip->ecc.size == 512)
1936 /* Default to Hamming for 1-bit ECC, if unspecified */
1937 chip->ecc.algo = NAND_ECC_HAMMING;
1938 else
1939 /* Otherwise, BCH */
1940 chip->ecc.algo = NAND_ECC_BCH;
1941 }
1942
1943 if (chip->ecc.algo == NAND_ECC_HAMMING && (chip->ecc.strength != 1 ||
1944 chip->ecc.size != 512)) {
1945 dev_err(ctrl->dev, "invalid Hamming params: %d bits per %d bytes\n",
1946 chip->ecc.strength, chip->ecc.size);
1947 return -EINVAL;
1948 }
1949
1928 switch (chip->ecc.size) { 1950 switch (chip->ecc.size) {
1929 case 512: 1951 case 512:
1930 if (chip->ecc.strength == 1) /* Hamming */ 1952 if (chip->ecc.algo == NAND_ECC_HAMMING)
1931 cfg->ecc_level = 15; 1953 cfg->ecc_level = 15;
1932 else 1954 else
1933 cfg->ecc_level = chip->ecc.strength; 1955 cfg->ecc_level = chip->ecc.strength;