Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 666b6568 authored by Brian Norris's avatar Brian Norris Committed by Boris Brezillon
Browse files

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: default avatarBrian Norris <computersforpeace@gmail.com>
Tested-by: default avatarRafał Miłecki <zajec5@gmail.com>
Signed-off-by: default avatarBoris Brezillon <boris.brezillon@free-electrons.com>
parent bd2e778c
Loading
Loading
Loading
Loading
+23 −1
Original line number Diff line number Diff line
@@ -1925,9 +1925,31 @@ static int brcmnand_setup_dev(struct brcmnand_host *host)
	cfg->col_adr_bytes = 2;
	cfg->blk_adr_bytes = get_blk_adr_bytes(mtd->size, mtd->writesize);

	if (chip->ecc.mode != NAND_ECC_HW) {
		dev_err(ctrl->dev, "only HW ECC supported; selected: %d\n",
			chip->ecc.mode);
		return -EINVAL;
	}

	if (chip->ecc.algo == NAND_ECC_UNKNOWN) {
		if (chip->ecc.strength == 1 && chip->ecc.size == 512)
			/* Default to Hamming for 1-bit ECC, if unspecified */
			chip->ecc.algo = NAND_ECC_HAMMING;
		else
			/* Otherwise, BCH */
			chip->ecc.algo = NAND_ECC_BCH;
	}

	if (chip->ecc.algo == NAND_ECC_HAMMING && (chip->ecc.strength != 1 ||
						   chip->ecc.size != 512)) {
		dev_err(ctrl->dev, "invalid Hamming params: %d bits per %d bytes\n",
			chip->ecc.strength, chip->ecc.size);
		return -EINVAL;
	}

	switch (chip->ecc.size) {
	case 512:
		if (chip->ecc.strength == 1) /* Hamming */
		if (chip->ecc.algo == NAND_ECC_HAMMING)
			cfg->ecc_level = 15;
		else
			cfg->ecc_level = chip->ecc.strength;