public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* [PATCH] mtd: nand: gpmi: Fix ecc strength calculation
@ 2016-06-21 14:35 Sascha Hauer
  2016-06-21 14:46 ` Boris Brezillon
  0 siblings, 1 reply; 5+ messages in thread
From: Sascha Hauer @ 2016-06-21 14:35 UTC (permalink / raw)
  To: linux-mtd; +Cc: Han Xu, Boris Brezillon, Sascha Hauer

BCH ECC correction works in chunks of 512 bytes, so a 2k page size nand
is divided into 4 chunks. Hardware requires that each chunk has a full
number of bytes, so when we need 9 bits per chunk we must round up to
two bytes. The current code misses that and calculates a ECC strength
of 18 for a 2048+128 byte page size NAND. ECC strength of 18 requires
30 bytes per chunk, so a total of 4 * (512 + 30) + 10 = 2178 bytes when
the device only has a page size of 2176 bytes.

Fix this by first calculating the number of bytes per chunk we have
available for ECC which also makes it easier to follow the calculation.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 28 ++++++++--------------------
 1 file changed, 8 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index 6e46156..95fb3dc 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -119,32 +119,20 @@ static irqreturn_t bch_irq(int irq, void *cookie)
 	return IRQ_HANDLED;
 }
 
-/*
- *  Calculate the ECC strength by hand:
- *	E : The ECC strength.
- *	G : the length of Galois Field.
- *	N : The chunk count of per page.
- *	O : the oobsize of the NAND chip.
- *	M : the metasize of per page.
- *
- *	The formula is :
- *		E * G * N
- *	      ------------ <= (O - M)
- *                  8
- *
- *      So, we get E by:
- *                    (O - M) * 8
- *              E <= -------------
- *                       G * N
- */
 static inline int get_ecc_strength(struct gpmi_nand_data *this)
 {
 	struct bch_geometry *geo = &this->bch_geometry;
 	struct mtd_info	*mtd = nand_to_mtd(&this->nand);
 	int ecc_strength;
+	int n;
+
+	/* number of ecc bytes we have per chunk */
+	n = (mtd->oobsize - geo->metadata_size) / geo->ecc_chunk_count;
+
+	/* in bits */
+	n <<= 3;
 
-	ecc_strength = ((mtd->oobsize - geo->metadata_size) * 8)
-			/ (geo->gf_len * geo->ecc_chunk_count);
+	ecc_strength = n / geo->gf_len;
 
 	/* We need the minor even number. */
 	return round_down(ecc_strength, 2);
-- 
2.8.1

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-06-22  8:34 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-06-21 14:35 [PATCH] mtd: nand: gpmi: Fix ecc strength calculation Sascha Hauer
2016-06-21 14:46 ` Boris Brezillon
2016-06-21 15:52   ` Han Xu
2016-06-22  6:33     ` Sascha Hauer
2016-06-22  8:34       ` Boris Brezillon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox