public inbox for linux-mtd@lists.infradead.org
 help / color / mirror / Atom feed
* Per-partition NAND ECC?
@ 2012-09-24 15:04 Peter Barada
  2012-09-24 15:29 ` Andreas Bießmann
  0 siblings, 1 reply; 2+ messages in thread
From: Peter Barada @ 2012-09-24 15:04 UTC (permalink / raw)
  To: linux-mtd@lists.infradead.org

On the OMAP3 parts the bootrom has a hard requirement of using 1-bit
Hamming ECC to read the 2nd stage bootloader(x-loader / SPL) out of the
first four blocks of NAND.  The Micron MT29C4G48MAZAPAKQ5 PoP part we're
using requires 4-bit ECC for all the other NAND blocks to maintain an
acceptable UBER.

Currently this wasn't a problem since I could use u-boot to update the
2nd stage bootloader. I now have a need to be able to update the 2nd
stage bootloader from Linux only so I need the ability to write/read
pages in a NAND partition with a different ECC method than that
specified over the device.  I think it would be more elegant to solve
this by allowing partition entry/mtdparts to specify its ECC
methodology, track that as part of the MTD device down into the nand
driver, and switch ECC methods/entrypoints as it changes.

Does anyone have suggestions on how to best approach this?

Thanks in advance!

-- 
Peter Barada
peter.barada@gmail.com

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

* Re: Per-partition NAND ECC?
  2012-09-24 15:04 Per-partition NAND ECC? Peter Barada
@ 2012-09-24 15:29 ` Andreas Bießmann
  0 siblings, 0 replies; 2+ messages in thread
From: Andreas Bießmann @ 2012-09-24 15:29 UTC (permalink / raw)
  To: Peter Barada; +Cc: linux-mtd@lists.infradead.org

On 24.09.2012 17:04, Peter Barada wrote:
> On the OMAP3 parts the bootrom has a hard requirement of using 1-bit
> Hamming ECC to read the 2nd stage bootloader(x-loader / SPL) out of the
> first four blocks of NAND.  The Micron MT29C4G48MAZAPAKQ5 PoP part we're
> using requires 4-bit ECC for all the other NAND blocks to maintain an
> acceptable UBER.
> 
> Currently this wasn't a problem since I could use u-boot to update the
> 2nd stage bootloader. I now have a need to be able to update the 2nd
> stage bootloader from Linux only so I need the ability to write/read
> pages in a NAND partition with a different ECC method than that
> specified over the device.  I think it would be more elegant to solve
> this by allowing partition entry/mtdparts to specify its ECC
> methodology, track that as part of the MTD device down into the nand
> driver, and switch ECC methods/entrypoints as it changes.
> 
> Does anyone have suggestions on how to best approach this?

We have the same problem here. We modified the omap2 nand driver to have
the ecc type configurable as module parameter.
In our upgrade scenario we can unload the omap2 module cause we are
running from initrd and so we can switch the ecc type by module
parameter quite easy.
Your suggestion to switch ecc per mtd sound way better, but sorry I have
currently no insights how to implement this in a proper way. I don't
know if there is an generic way to bind the ecc information to an mtd.
You can find our solution attached (is added by c'n'p thus may have
wrong line wraps). If anybody is interested in this solution, I can
provide a proper patch.
And beware, you will need [1] and [2] for safe unloading of omap2 nand
driver.

Best regards

Andreas Bießmann

[1]
http://git.infradead.org/users/dedekind/l2-mtd.git/commit/44552d26885a25b423c6606fd5f203aa95dc953f
[2]
http://git.infradead.org/users/dedekind/l2-mtd.git/commit/14178ea6dd8a6575616ce439389a8dd45e149aa8

---
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
index c2b0bba..7f2ca2e 100644
--- a/drivers/mtd/nand/omap2.c
+++ b/drivers/mtd/nand/omap2.c
@@ -95,6 +95,10 @@
 #define P4e_s(a)	(TF(a & NAND_Ecc_P4e)		<< 0)
 #define P4o_s(a)	(TF(a & NAND_Ecc_P4o)		<< 1)

+static int eccmode = -1;
+module_param(eccmode, int, 0);
+MODULE_PARM_DESC(eccmode, "ECC mode (-1=platform data, 0=sw, 1=hw,
2=hwrom)");
+
 /* oob info generated runtime depending on ecc algorithm and layout
selected */
 static struct nand_ecclayout omap_oobinfo;
 /* Define some generic bad / good block scan pattern which are used
@@ -931,6 +935,7 @@ static int __devinit omap_nand_probe(struct
platform_device *pdev)
 	struct omap_nand_platform_data	*pdata;
 	int				err;
 	int				i, offset;
+	enum omap_ecc			ecc_opt;

 	pdata = pdev->dev.platform_data;
 	if (pdata == NULL) {
@@ -1052,10 +1057,13 @@ static int __devinit omap_nand_probe(struct
platform_device *pdev)
 	info->nand.verify_buf = omap_verify_buf;

 	/* selsect the ecc type */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
+	ecc_opt = (eccmode == -1) ? pdata->ecc_opt : eccmode;
+	dev_info(&pdev->dev, "Using ECC mode %d\n", ecc_opt);
+
+	if (ecc_opt == OMAP_ECC_HAMMING_CODE_DEFAULT)
 		info->nand.ecc.mode = NAND_ECC_SOFT;
-	else if ((pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
-		(pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
+	else if ((ecc_opt == OMAP_ECC_HAMMING_CODE_HW) ||
+		(ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE)) {
 		info->nand.ecc.bytes            = 3;
 		info->nand.ecc.size             = 512;
 		info->nand.ecc.strength         = 1;
@@ -1077,7 +1085,7 @@ static int __devinit omap_nand_probe(struct
platform_device *pdev)
 	}

 	/* rom code layout */
-	if (pdata->ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {
+	if (ecc_opt == OMAP_ECC_HAMMING_CODE_HW_ROMCODE) {

 		if (info->nand.options & NAND_BUSWIDTH_16)
 			offset = 2;

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

end of thread, other threads:[~2012-09-24 15:29 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-24 15:04 Per-partition NAND ECC? Peter Barada
2012-09-24 15:29 ` Andreas Bießmann

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