* [PATCH 1/4] mtd: nand: pxa3xx: Normalize ECC strength for ECC scheme selection
2014-03-17 15:47 [PATCH 0/4] pxa3xx-nand: Allow to specify an ECC scheme through DT Ezequiel Garcia
@ 2014-03-17 15:47 ` Ezequiel Garcia
2014-03-20 17:39 ` Ezequiel Garcia
2014-03-17 15:47 ` [PATCH 2/4] mtd: nand: pxa3xx: Clean pxa_ecc_init() error handling Ezequiel Garcia
` (2 subsequent siblings)
3 siblings, 1 reply; 6+ messages in thread
From: Ezequiel Garcia @ 2014-03-17 15:47 UTC (permalink / raw)
To: linux-mtd, Brian Norris
Cc: Lior Amsalem, Thomas Petazzoni, Tawfik Bayouk, Seif Mazareeb,
Simon Guinot, Ezequiel Garcia, Gregory Clement, Willy Tarreau
As preparation work to use the ECC devicetree binding, let's normalize
the ECC strength to a 512B step size. This will allow comparison between
different strengths.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 7588fe2..0196e33 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1344,10 +1344,9 @@ static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
}
static int pxa_ecc_init(struct pxa3xx_nand_info *info,
- struct nand_ecc_ctrl *ecc,
- int strength, int ecc_stepsize, int page_size)
+ struct nand_ecc_ctrl *ecc, int strength, int page_size)
{
- if (strength == 1 && ecc_stepsize == 512 && page_size == 2048) {
+ if (strength == 1 && page_size == 2048) {
info->chunk_size = 2048;
info->spare_size = 40;
info->ecc_size = 24;
@@ -1356,7 +1355,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->strength = 1;
return 1;
- } else if (strength == 1 && ecc_stepsize == 512 && page_size == 512) {
+ } else if (strength == 1 && page_size == 512) {
info->chunk_size = 512;
info->spare_size = 8;
info->ecc_size = 8;
@@ -1369,7 +1368,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
* Required ECC: 4-bit correction per 512 bytes
* Select: 16-bit correction per 2048 bytes
*/
- } else if (strength == 4 && ecc_stepsize == 512 && page_size == 2048) {
+ } else if (strength == 4 && page_size == 2048) {
info->ecc_bch = 1;
info->chunk_size = 2048;
info->spare_size = 32;
@@ -1380,7 +1379,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->strength = 16;
return 1;
- } else if (strength == 4 && ecc_stepsize == 512 && page_size == 4096) {
+ } else if (strength == 4 && page_size == 4096) {
info->ecc_bch = 1;
info->chunk_size = 2048;
info->spare_size = 32;
@@ -1395,7 +1394,7 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
* Required ECC: 8-bit correction per 512 bytes
* Select: 16-bit correction per 1024 bytes
*/
- } else if (strength == 8 && ecc_stepsize == 512 && page_size == 4096) {
+ } else if (strength == 8 && page_size == 4096) {
info->ecc_bch = 1;
info->chunk_size = 1024;
info->spare_size = 0;
@@ -1525,8 +1524,8 @@ KEEP_CONFIG:
ecc_step = 512;
}
- ret = pxa_ecc_init(info, &chip->ecc, ecc_strength,
- ecc_step, mtd->writesize);
+ ret = pxa_ecc_init(info, &chip->ecc, (ecc_strength * ecc_step) / 512,
+ mtd->writesize);
if (!ret) {
dev_err(&info->pdev->dev,
"ECC strength %d at page size %d is not supported\n",
--
1.9.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 1/4] mtd: nand: pxa3xx: Normalize ECC strength for ECC scheme selection
2014-03-17 15:47 ` [PATCH 1/4] mtd: nand: pxa3xx: Normalize ECC strength for ECC scheme selection Ezequiel Garcia
@ 2014-03-20 17:39 ` Ezequiel Garcia
0 siblings, 0 replies; 6+ messages in thread
From: Ezequiel Garcia @ 2014-03-20 17:39 UTC (permalink / raw)
To: linux-mtd, Brian Norris
Cc: Lior Amsalem, Thomas Petazzoni, Tawfik Bayouk, Seif Mazareeb,
Simon Guinot, Gregory Clement, Willy Tarreau
On Mar 17, Ezequiel Garcia wrote:
> @@ -1525,8 +1524,8 @@ KEEP_CONFIG:
> ecc_step = 512;
> }
>
> - ret = pxa_ecc_init(info, &chip->ecc, ecc_strength,
> - ecc_step, mtd->writesize);
> + ret = pxa_ecc_init(info, &chip->ecc, (ecc_strength * ecc_step) / 512,
> + mtd->writesize);
After a test report from Simon Guinot we found this normalization is horribly
wrong. It should be: (ecc_strength * 512) / ecc_step. I'll prepare a v2 and
make sure to test it properly this time!
--
Ezequiel García, Free Electrons
Embedded Linux, Kernel and Android Engineering
http://free-electrons.com
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/4] mtd: nand: pxa3xx: Clean pxa_ecc_init() error handling
2014-03-17 15:47 [PATCH 0/4] pxa3xx-nand: Allow to specify an ECC scheme through DT Ezequiel Garcia
2014-03-17 15:47 ` [PATCH 1/4] mtd: nand: pxa3xx: Normalize ECC strength for ECC scheme selection Ezequiel Garcia
@ 2014-03-17 15:47 ` Ezequiel Garcia
2014-03-17 15:47 ` [PATCH 3/4] mtd: nand: pxa3xx: Use ECC strength and step size devicetree binding Ezequiel Garcia
2014-03-17 15:47 ` [PATCH 4/4] mtd: nand: pxa3xx: Add supported ECC strength and step size to the DT binding Ezequiel Garcia
3 siblings, 0 replies; 6+ messages in thread
From: Ezequiel Garcia @ 2014-03-17 15:47 UTC (permalink / raw)
To: linux-mtd, Brian Norris
Cc: Lior Amsalem, Thomas Petazzoni, Tawfik Bayouk, Seif Mazareeb,
Simon Guinot, Ezequiel Garcia, Gregory Clement, Willy Tarreau
Let's make pxa_ecc_init() return a negative errno on error or zero
if succesful, which is standard kernel practice. Also, report the
selected ECC strength and step size, which is important information.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 0196e33..092a17c 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1353,7 +1353,6 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->mode = NAND_ECC_HW;
ecc->size = 512;
ecc->strength = 1;
- return 1;
} else if (strength == 1 && page_size == 512) {
info->chunk_size = 512;
@@ -1362,7 +1361,6 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->mode = NAND_ECC_HW;
ecc->size = 512;
ecc->strength = 1;
- return 1;
/*
* Required ECC: 4-bit correction per 512 bytes
@@ -1388,7 +1386,6 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->size = info->chunk_size;
ecc->layout = &ecc_layout_4KB_bch4bit;
ecc->strength = 16;
- return 1;
/*
* Required ECC: 8-bit correction per 512 bytes
@@ -1403,8 +1400,15 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->size = info->chunk_size;
ecc->layout = &ecc_layout_4KB_bch8bit;
ecc->strength = 16;
- return 1;
+ } else {
+ dev_err(&info->pdev->dev,
+ "ECC strength %d at page size %d is not supported\n",
+ strength, page_size);
+ return -ENODEV;
}
+
+ dev_info(&info->pdev->dev, "ECC strength %d, ECC step size %d\n",
+ ecc->strength, ecc->size);
return 0;
}
@@ -1526,12 +1530,8 @@ KEEP_CONFIG:
ret = pxa_ecc_init(info, &chip->ecc, (ecc_strength * ecc_step) / 512,
mtd->writesize);
- if (!ret) {
- dev_err(&info->pdev->dev,
- "ECC strength %d at page size %d is not supported\n",
- ecc_strength, mtd->writesize);
- return -ENODEV;
- }
+ if (ret)
+ return ret;
/* calculate addressing information */
if (mtd->writesize >= 2048)
--
1.9.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/4] mtd: nand: pxa3xx: Use ECC strength and step size devicetree binding
2014-03-17 15:47 [PATCH 0/4] pxa3xx-nand: Allow to specify an ECC scheme through DT Ezequiel Garcia
2014-03-17 15:47 ` [PATCH 1/4] mtd: nand: pxa3xx: Normalize ECC strength for ECC scheme selection Ezequiel Garcia
2014-03-17 15:47 ` [PATCH 2/4] mtd: nand: pxa3xx: Clean pxa_ecc_init() error handling Ezequiel Garcia
@ 2014-03-17 15:47 ` Ezequiel Garcia
2014-03-17 15:47 ` [PATCH 4/4] mtd: nand: pxa3xx: Add supported ECC strength and step size to the DT binding Ezequiel Garcia
3 siblings, 0 replies; 6+ messages in thread
From: Ezequiel Garcia @ 2014-03-17 15:47 UTC (permalink / raw)
To: linux-mtd, Brian Norris
Cc: Lior Amsalem, Thomas Petazzoni, Tawfik Bayouk, Seif Mazareeb,
Simon Guinot, Ezequiel Garcia, Gregory Clement, Willy Tarreau
This commit adds support for the user to specify the ECC strength
and step size throught the devicetree. We keep the previous behavior,
if there's no DT parameter passed.
Also, if there is an ONFI-specified minimum ECC strength requirement,
and the devicetree specified ECC strength is weaker, print a warning
and try to select the ONFI-specified strength.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
---
drivers/mtd/nand/pxa3xx_nand.c | 47 +++++++++++++++++++--------
include/linux/platform_data/mtd-nand-pxa3xx.h | 3 ++
2 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/drivers/mtd/nand/pxa3xx_nand.c b/drivers/mtd/nand/pxa3xx_nand.c
index 092a17c..a4499e6 100644
--- a/drivers/mtd/nand/pxa3xx_nand.c
+++ b/drivers/mtd/nand/pxa3xx_nand.c
@@ -1344,8 +1344,30 @@ static int pxa3xx_nand_sensing(struct pxa3xx_nand_info *info)
}
static int pxa_ecc_init(struct pxa3xx_nand_info *info,
- struct nand_ecc_ctrl *ecc, int strength, int page_size)
+ struct nand_chip *chip,
+ struct pxa3xx_nand_platform_data *pdata,
+ unsigned int page_size)
{
+ struct nand_ecc_ctrl *ecc = &chip->ecc;
+ unsigned int strength, onfi_strength;
+
+ /* We need to normalize the ECC strengths, in order to compare them. */
+ strength = (pdata->ecc_strength * pdata->ecc_step_size) / 512;
+ onfi_strength = (chip->ecc_strength_ds * chip->ecc_step_ds) / 512;
+
+ /*
+ * The user requested ECC strength cannot be weaker than the ONFI
+ * minimum specified ECC strength.
+ */
+ if (strength && strength < onfi_strength) {
+ dev_warn(&info->pdev->dev,
+ "requested ECC strength is too weak\n");
+ strength = onfi_strength;
+ }
+
+ if (!strength)
+ strength = onfi_strength ? onfi_strength : 1;
+
if (strength == 1 && page_size == 2048) {
info->chunk_size = 2048;
info->spare_size = 40;
@@ -1375,7 +1397,6 @@ static int pxa_ecc_init(struct pxa3xx_nand_info *info,
ecc->size = info->chunk_size;
ecc->layout = &ecc_layout_2KB_bch4bit;
ecc->strength = 16;
- return 1;
} else if (strength == 4 && page_size == 4096) {
info->ecc_bch = 1;
@@ -1424,7 +1445,6 @@ static int pxa3xx_nand_scan(struct mtd_info *mtd)
uint32_t id = -1;
uint64_t chipsize;
int i, ret, num;
- uint16_t ecc_strength, ecc_step;
if (pdata->keep_config && !pxa3xx_nand_detect_config(info))
goto KEEP_CONFIG;
@@ -1519,17 +1539,8 @@ KEEP_CONFIG:
}
}
- ecc_strength = chip->ecc_strength_ds;
- ecc_step = chip->ecc_step_ds;
-
- /* Set default ECC strength requirements on non-ONFI devices */
- if (ecc_strength < 1 && ecc_step < 1) {
- ecc_strength = 1;
- ecc_step = 512;
- }
-
- ret = pxa_ecc_init(info, &chip->ecc, (ecc_strength * ecc_step) / 512,
- mtd->writesize);
+ /* Selects an ECC and fills pxa3xx_nand_info and nand_chip */
+ ret = pxa_ecc_init(info, chip, pdata, mtd->writesize);
if (ret)
return ret;
@@ -1729,6 +1740,14 @@ static int pxa3xx_nand_probe_dt(struct platform_device *pdev)
of_property_read_u32(np, "num-cs", &pdata->num_cs);
pdata->flash_bbt = of_get_nand_on_flash_bbt(np);
+ pdata->ecc_strength = of_get_nand_ecc_strength(np);
+ if (pdata->ecc_strength < 0)
+ pdata->ecc_strength = 0;
+
+ pdata->ecc_step_size = of_get_nand_ecc_step_size(np);
+ if (pdata->ecc_step_size < 0)
+ pdata->ecc_step_size = 0;
+
pdev->dev.platform_data = pdata;
return 0;
diff --git a/include/linux/platform_data/mtd-nand-pxa3xx.h b/include/linux/platform_data/mtd-nand-pxa3xx.h
index a941471..5c0f2e3 100644
--- a/include/linux/platform_data/mtd-nand-pxa3xx.h
+++ b/include/linux/platform_data/mtd-nand-pxa3xx.h
@@ -58,6 +58,9 @@ struct pxa3xx_nand_platform_data {
/* use an flash-based bad block table */
bool flash_bbt;
+ /* requested ECC strength and ECC step size */
+ unsigned int ecc_strength, ecc_step_size;
+
const struct mtd_partition *parts[NUM_CHIP_SELECT];
unsigned int nr_parts[NUM_CHIP_SELECT];
--
1.9.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 4/4] mtd: nand: pxa3xx: Add supported ECC strength and step size to the DT binding
2014-03-17 15:47 [PATCH 0/4] pxa3xx-nand: Allow to specify an ECC scheme through DT Ezequiel Garcia
` (2 preceding siblings ...)
2014-03-17 15:47 ` [PATCH 3/4] mtd: nand: pxa3xx: Use ECC strength and step size devicetree binding Ezequiel Garcia
@ 2014-03-17 15:47 ` Ezequiel Garcia
3 siblings, 0 replies; 6+ messages in thread
From: Ezequiel Garcia @ 2014-03-17 15:47 UTC (permalink / raw)
To: linux-mtd, Brian Norris
Cc: Lior Amsalem, Thomas Petazzoni, Tawfik Bayouk, Seif Mazareeb,
Simon Guinot, Ezequiel Garcia, Gregory Clement, Willy Tarreau
This commit updated the devicetree binding documentation for this driver
with the supported ECC strength and step size combinations.
Signed-off-by: Ezequiel Garcia <ezequiel.garcia@free-electrons.com>
---
Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
index 86e0a56..650c0dc 100644
--- a/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
+++ b/Documentation/devicetree/bindings/mtd/pxa3xx-nand.txt
@@ -17,6 +17,14 @@ Optional properties:
- num-cs: Number of chipselect lines to usw
- nand-on-flash-bbt: boolean to enable on flash bbt option if
not present false
+ - nand-ecc-strength: number of bits to correct per ECC step
+ - nand-ecc-step-size: number of data bytes covered by a single ECC step
+
+The following ECC strength and step size are currently supported:
+
+ - nand-ecc-strength = <1>, nand-ecc-step-size = <512> (aka Hamming)
+ - nand-ecc-strength = <16>, nand-ecc-step-size = <2048> (aka BCH-4)
+ - nand-ecc-strength = <16>, nand-ecc-step-size = <1024> (aka BCH-8)
Example:
--
1.9.0
^ permalink raw reply related [flat|nested] 6+ messages in thread