linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
@ 2021-09-08 20:16 Bert Vermeulen
  2021-09-14 17:31 ` Miquel Raynal
  2021-09-15  8:13 ` Frieder Schrempf
  0 siblings, 2 replies; 6+ messages in thread
From: Bert Vermeulen @ 2021-09-08 20:16 UTC (permalink / raw)
  To: Miquel Raynal, Richard Weinberger, Vignesh Raghavendra,
	Bert Vermeulen, Patrice Chotard, Boris Brezillon,
	Christophe Kerello, Mark Brown, Alexander Lobakin, linux-kernel,
	linux-mtd

This adds a new vendor Etron, and support for a 2Gb chip.

The datasheet is available at
https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf

Signed-off-by: Bert Vermeulen <bert@biot.com>
---
v2:
- Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
  hardcoded to this 2Gb chip only
- Fixed manufacturer ordering
- Fixed minor formatting issues as reported
- Removed debug comment

 drivers/mtd/nand/spi/Makefile |   2 +-
 drivers/mtd/nand/spi/core.c   |   1 +
 drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
 include/linux/mtd/spinand.h   |   1 +
 4 files changed, 107 insertions(+), 1 deletion(-)
 create mode 100644 drivers/mtd/nand/spi/etron.c

diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index 9662b9c1d5a9..cc3c4e046ea9 100644
--- a/drivers/mtd/nand/spi/Makefile
+++ b/drivers/mtd/nand/spi/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0
-spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
+spinand-objs := core.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
 obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index 446ba8d43fbc..2cbf25b8caa2 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -894,6 +894,7 @@ static const struct nand_ops spinand_ops = {
 };
 
 static const struct spinand_manufacturer *spinand_manufacturers[] = {
+	&etron_spinand_manufacturer,
 	&gigadevice_spinand_manufacturer,
 	&macronix_spinand_manufacturer,
 	&micron_spinand_manufacturer,
diff --git a/drivers/mtd/nand/spi/etron.c b/drivers/mtd/nand/spi/etron.c
new file mode 100644
index 000000000000..1a92b9cf3043
--- /dev/null
+++ b/drivers/mtd/nand/spi/etron.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_ETRON			0xd5
+
+static SPINAND_OP_VARIANTS(read_cache_variants,
+		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
+		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
+
+static SPINAND_OP_VARIANTS(write_cache_variants,
+		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
+		SPINAND_PROG_LOAD(true, 0, NULL, 0));
+
+static SPINAND_OP_VARIANTS(update_cache_variants,
+		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
+		SPINAND_PROG_LOAD(false, 0, NULL, 0));
+
+static int etron_oob_spare(struct mtd_info *mtd)
+{
+	if (mtd->size < 0x10000000)
+		return mtd->oobsize / 2;
+	else
+		return mtd->oobsize / 2 + mtd->oobsize / 16;
+}
+
+static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
+					struct mtd_oob_region *oobregion)
+{
+	if (section)
+		return -ERANGE;
+
+	oobregion->offset = etron_oob_spare(mtd);
+	oobregion->length = mtd->oobsize - oobregion->offset;
+
+	return 0;
+}
+
+static int etron_ooblayout_free(struct mtd_info *mtd, int section,
+			   struct mtd_oob_region *oobregion)
+{
+	if (section)
+		return -ERANGE;
+
+	oobregion->offset = 2;
+	oobregion->length = etron_oob_spare(mtd) - 2;
+
+	return 0;
+}
+
+static const struct mtd_ooblayout_ops etron_ooblayout = {
+	.ecc = etron_ooblayout_ecc,
+	.free = etron_ooblayout_free,
+};
+
+static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
+{
+	switch (status & STATUS_ECC_MASK) {
+	case STATUS_ECC_NO_BITFLIPS:
+		return 0;
+
+	case STATUS_ECC_HAS_BITFLIPS:
+		/* Between 1-7 bitflips were corrected */
+		return 7;
+
+	case STATUS_ECC_MASK:
+		/* Maximum bitflips were corrected */
+		return 8;
+
+	case STATUS_ECC_UNCOR_ERROR:
+		return -EBADMSG;
+	}
+
+	return -EINVAL;
+}
+
+static const struct spinand_info etron_spinand_table[] = {
+	SPINAND_INFO("EM73D044VCx",
+		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f),
+		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
+		     NAND_ECCREQ(8, 512),
+		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+					      &write_cache_variants,
+					      &update_cache_variants),
+		     SPINAND_HAS_QE_BIT,
+		     SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
+};
+
+static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
+};
+
+const struct spinand_manufacturer etron_spinand_manufacturer = {
+	.id = SPINAND_MFR_ETRON,
+	.name = "Etron",
+	.chips = etron_spinand_table,
+	.nchips = ARRAY_SIZE(etron_spinand_table),
+	.ops = &etron_spinand_manuf_ops,
+};
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6988956b8492..d7c0a0439652 100644
--- a/include/linux/mtd/spinand.h
+++ b/include/linux/mtd/spinand.h
@@ -260,6 +260,7 @@ struct spinand_manufacturer {
 };
 
 /* SPI NAND manufacturers */
+extern const struct spinand_manufacturer etron_spinand_manufacturer;
 extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
 extern const struct spinand_manufacturer macronix_spinand_manufacturer;
 extern const struct spinand_manufacturer micron_spinand_manufacturer;
-- 
2.25.1


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

* Re: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
  2021-09-08 20:16 [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx Bert Vermeulen
@ 2021-09-14 17:31 ` Miquel Raynal
  2021-09-14 17:49   ` Richard Weinberger
  2021-09-15  8:13 ` Frieder Schrempf
  1 sibling, 1 reply; 6+ messages in thread
From: Miquel Raynal @ 2021-09-14 17:31 UTC (permalink / raw)
  To: Richard Weinberger
  Cc: Bert Vermeulen, Vignesh Raghavendra, Patrice Chotard,
	Boris Brezillon, Christophe Kerello, Mark Brown,
	Alexander Lobakin, linux-kernel, linux-mtd

Hi Bert,

Richard, a question for you below!

bert@biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:

> This adds a new vendor Etron, and support for a 2Gb chip.
> 
> The datasheet is available at
> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
> 
> Signed-off-by: Bert Vermeulen <bert@biot.com>
> ---
> v2:
> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>   hardcoded to this 2Gb chip only
> - Fixed manufacturer ordering
> - Fixed minor formatting issues as reported
> - Removed debug comment
> 
>  drivers/mtd/nand/spi/Makefile |   2 +-
>  drivers/mtd/nand/spi/core.c   |   1 +
>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>  include/linux/mtd/spinand.h   |   1 +
>  4 files changed, 107 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/mtd/nand/spi/etron.c

[...]

> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
> +{
> +	switch (status & STATUS_ECC_MASK) {
> +	case STATUS_ECC_NO_BITFLIPS:
> +		return 0;
> +
> +	case STATUS_ECC_HAS_BITFLIPS:
> +		/* Between 1-7 bitflips were corrected */
> +		return 7;

Mmmh this is a bit problematic, having no intermediate value means a
single bitflip will trigger UBI to move the data around as its
threshold will be reached. Richard, any feedback on this?

> +
> +	case STATUS_ECC_MASK:
> +		/* Maximum bitflips were corrected */
> +		return 8;
> +
> +	case STATUS_ECC_UNCOR_ERROR:
> +		return -EBADMSG;
> +	}
> +
> +	return -EINVAL;
> +}

Thanks,
Miquèl

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

* Re: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
  2021-09-14 17:31 ` Miquel Raynal
@ 2021-09-14 17:49   ` Richard Weinberger
  2021-09-14 20:03     ` Bert Vermeulen
  0 siblings, 1 reply; 6+ messages in thread
From: Richard Weinberger @ 2021-09-14 17:49 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Bert Vermeulen, Vignesh Raghavendra, Patrice Chotard,
	Boris Brezillon, Christophe Kerello, Mark Brown,
	Alexander Lobakin, linux-kernel, linux-mtd

----- Ursprüngliche Mail -----
> Von: "Miquel Raynal" <miquel.raynal@bootlin.com>
> An: "richard" <richard@nod.at>
> CC: "Bert Vermeulen" <bert@biot.com>, "Vignesh Raghavendra" <vigneshr@ti.com>, "Patrice Chotard"
> <patrice.chotard@foss.st.com>, "Boris Brezillon" <boris.brezillon@collabora.com>, "Christophe Kerello"
> <christophe.kerello@foss.st.com>, "Mark Brown" <broonie@kernel.org>, "Alexander Lobakin" <alobakin@pm.me>,
> "linux-kernel" <linux-kernel@vger.kernel.org>, "linux-mtd" <linux-mtd@lists.infradead.org>
> Gesendet: Dienstag, 14. September 2021 19:31:08
> Betreff: Re: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx

> Hi Bert,
> 
> Richard, a question for you below!

:)
 
> bert@biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:
> 
>> This adds a new vendor Etron, and support for a 2Gb chip.
>> 
>> The datasheet is available at
>> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
>> 
>> Signed-off-by: Bert Vermeulen <bert@biot.com>
>> ---
>> v2:
>> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>>   hardcoded to this 2Gb chip only
>> - Fixed manufacturer ordering
>> - Fixed minor formatting issues as reported
>> - Removed debug comment
>> 
>>  drivers/mtd/nand/spi/Makefile |   2 +-
>>  drivers/mtd/nand/spi/core.c   |   1 +
>>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>>  include/linux/mtd/spinand.h   |   1 +
>>  4 files changed, 107 insertions(+), 1 deletion(-)
>>  create mode 100644 drivers/mtd/nand/spi/etron.c
> 
> [...]
> 
>> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
>> +{
>> +	switch (status & STATUS_ECC_MASK) {
>> +	case STATUS_ECC_NO_BITFLIPS:
>> +		return 0;
>> +
>> +	case STATUS_ECC_HAS_BITFLIPS:
>> +		/* Between 1-7 bitflips were corrected */
>> +		return 7;
> 
> Mmmh this is a bit problematic, having no intermediate value means a
> single bitflip will trigger UBI to move the data around as its
> threshold will be reached. Richard, any feedback on this?

So, the NAND controller can only report "no bitflips", "some bitflips", "maximum biflips" and "no way to fix"?
If so, yes, this is problematic for UBI because it will trigger wear-leveling way too often.
On a medium aged NAND I'd expect to see STATUS_ECC_HAS_BITFLIPS almost always set. :-(

Thanks,
//richard

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

* Re: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
  2021-09-14 17:49   ` Richard Weinberger
@ 2021-09-14 20:03     ` Bert Vermeulen
  2021-09-15  7:13       ` Miquel Raynal
  0 siblings, 1 reply; 6+ messages in thread
From: Bert Vermeulen @ 2021-09-14 20:03 UTC (permalink / raw)
  To: Richard Weinberger, Miquel Raynal
  Cc: Vignesh Raghavendra, Patrice Chotard, Boris Brezillon,
	Christophe Kerello, Mark Brown, Alexander Lobakin, linux-kernel,
	linux-mtd

On 9/14/21 7:49 PM, Richard Weinberger wrote:
> ----- Ursprüngliche Mail -----
>> bert@biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:
>> 
>>> This adds a new vendor Etron, and support for a 2Gb chip.
>>> 
>>> The datasheet is available at
>>> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
>>> 
>>> Signed-off-by: Bert Vermeulen <bert@biot.com>
>>> ---
>>> v2:
>>> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>>>   hardcoded to this 2Gb chip only
>>> - Fixed manufacturer ordering
>>> - Fixed minor formatting issues as reported
>>> - Removed debug comment
>>> 
>>>  drivers/mtd/nand/spi/Makefile |   2 +-
>>>  drivers/mtd/nand/spi/core.c   |   1 +
>>>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>>>  include/linux/mtd/spinand.h   |   1 +
>>>  4 files changed, 107 insertions(+), 1 deletion(-)
>>>  create mode 100644 drivers/mtd/nand/spi/etron.c
>> 
>> [...]
>> 
>>> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
>>> +{
>>> +	switch (status & STATUS_ECC_MASK) {
>>> +	case STATUS_ECC_NO_BITFLIPS:
>>> +		return 0;
>>> +
>>> +	case STATUS_ECC_HAS_BITFLIPS:
>>> +		/* Between 1-7 bitflips were corrected */
>>> +		return 7;
>> 
>> Mmmh this is a bit problematic, having no intermediate value means a
>> single bitflip will trigger UBI to move the data around as its
>> threshold will be reached. Richard, any feedback on this?
> 
> So, the NAND controller can only report "no bitflips", "some bitflips", "maximum biflips" and "no way to fix"?
> If so, yes, this is problematic for UBI because it will trigger wear-leveling way too often.
> On a medium aged NAND I'd expect to see STATUS_ECC_HAS_BITFLIPS almost always set. :-(

Yes, that's all there is according to the datasheet. Can't be _that_
unusual, since that's all the STATUS_ECC_* flags cover.

Incidentally I'm abusing STATUS_ECC_MASK here, since the 0b11 pattern is
missing from those flags.


-- 
Bert Vermeulen
bert@biot.com

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

* Re: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
  2021-09-14 20:03     ` Bert Vermeulen
@ 2021-09-15  7:13       ` Miquel Raynal
  0 siblings, 0 replies; 6+ messages in thread
From: Miquel Raynal @ 2021-09-15  7:13 UTC (permalink / raw)
  To: Bert Vermeulen
  Cc: Richard Weinberger, Vignesh Raghavendra, Patrice Chotard,
	Boris Brezillon, Christophe Kerello, Mark Brown,
	Alexander Lobakin, linux-kernel, linux-mtd

Hi Bert,

bert@biot.com wrote on Tue, 14 Sep 2021 22:03:49 +0200:

> On 9/14/21 7:49 PM, Richard Weinberger wrote:
> > ----- Ursprüngliche Mail -----  
> >> bert@biot.com wrote on Wed,  8 Sep 2021 22:16:19 +0200:
> >>   
> >>> This adds a new vendor Etron, and support for a 2Gb chip.
> >>> 
> >>> The datasheet is available at
> >>> https://www.etron.com/cn/products/EM73%5B8%5DC%5BD_E_F%5DVC%20SPI%20NAND%20Flash_Promotion_Rev%201_00A.pdf
> >>> 
> >>> Signed-off-by: Bert Vermeulen <bert@biot.com>
> >>> ---
> >>> v2:
> >>> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
> >>>   hardcoded to this 2Gb chip only
> >>> - Fixed manufacturer ordering
> >>> - Fixed minor formatting issues as reported
> >>> - Removed debug comment
> >>> 
> >>>  drivers/mtd/nand/spi/Makefile |   2 +-
> >>>  drivers/mtd/nand/spi/core.c   |   1 +
> >>>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
> >>>  include/linux/mtd/spinand.h   |   1 +
> >>>  4 files changed, 107 insertions(+), 1 deletion(-)
> >>>  create mode 100644 drivers/mtd/nand/spi/etron.c  
> >> 
> >> [...]
> >>   
> >>> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
> >>> +{
> >>> +	switch (status & STATUS_ECC_MASK) {
> >>> +	case STATUS_ECC_NO_BITFLIPS:
> >>> +		return 0;
> >>> +
> >>> +	case STATUS_ECC_HAS_BITFLIPS:
> >>> +		/* Between 1-7 bitflips were corrected */
> >>> +		return 7;  
> >> 
> >> Mmmh this is a bit problematic, having no intermediate value means a
> >> single bitflip will trigger UBI to move the data around as its
> >> threshold will be reached. Richard, any feedback on this?  
> > 
> > So, the NAND controller can only report "no bitflips", "some bitflips", "maximum biflips" and "no way to fix"?
> > If so, yes, this is problematic for UBI because it will trigger wear-leveling way too often.
> > On a medium aged NAND I'd expect to see STATUS_ECC_HAS_BITFLIPS almost always set. :-(  
> 
> Yes, that's all there is according to the datasheet. Can't be _that_
> unusual, since that's all the STATUS_ECC_* flags cover.

I forgot about that part which was reminded to me by Richard:

https://elixir.bootlin.com/linux/latest/source/drivers/mtd/mtdcore.c#L627
	/* default value if not set by driver */
	if (mtd->bitflip_threshold == 0)
		mtd->bitflip_threshold = mtd->ecc_strength;

So this is fine.

Thanks,
Miquèl

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

* Re: [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx
  2021-09-08 20:16 [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx Bert Vermeulen
  2021-09-14 17:31 ` Miquel Raynal
@ 2021-09-15  8:13 ` Frieder Schrempf
  1 sibling, 0 replies; 6+ messages in thread
From: Frieder Schrempf @ 2021-09-15  8:13 UTC (permalink / raw)
  To: Bert Vermeulen, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Patrice Chotard, Boris Brezillon,
	Christophe Kerello, Mark Brown, Alexander Lobakin, linux-kernel,
	linux-mtd

Hi Bert,

On 08.09.21 22:16, Bert Vermeulen wrote:
> This adds a new vendor Etron, and support for a 2Gb chip.
> 
> The datasheet is available at
> https://eur04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwww.etron.com%2Fcn%2Fproducts%2FEM73%255B8%255DC%255BD_E_F%255DVC%2520SPI%2520NAND%2520Flash_Promotion_Rev%25201_00A.pdf&amp;data=04%7C01%7Cfrieder.schrempf%40kontron.de%7C871fa2a364d8484bbc0d08d97305f2f4%7C8c9d3c973fd941c8a2b1646f3942daf1%7C0%7C0%7C637667293724201439%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&amp;sdata=SeopP6Mvu1CHj6eB22XlO78NGnMc3hCFzM%2F5jKmJZxU%3D&amp;reserved=0
> 
> Signed-off-by: Bert Vermeulen <bert@biot.com>
> ---
> v2:
> - Made ooblayout_free/_ecc depend on chip-specific parameters, instead of
>   hardcoded to this 2Gb chip only
> - Fixed manufacturer ordering
> - Fixed minor formatting issues as reported
> - Removed debug comment
> 
>  drivers/mtd/nand/spi/Makefile |   2 +-
>  drivers/mtd/nand/spi/core.c   |   1 +
>  drivers/mtd/nand/spi/etron.c  | 104 ++++++++++++++++++++++++++++++++++
>  include/linux/mtd/spinand.h   |   1 +
>  4 files changed, 107 insertions(+), 1 deletion(-)
>  create mode 100644 drivers/mtd/nand/spi/etron.c
> 
> diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
> index 9662b9c1d5a9..cc3c4e046ea9 100644
> --- a/drivers/mtd/nand/spi/Makefile
> +++ b/drivers/mtd/nand/spi/Makefile
> @@ -1,3 +1,3 @@
>  # SPDX-License-Identifier: GPL-2.0
> -spinand-objs := core.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
> +spinand-objs := core.o etron.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o
>  obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
> diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
> index 446ba8d43fbc..2cbf25b8caa2 100644
> --- a/drivers/mtd/nand/spi/core.c
> +++ b/drivers/mtd/nand/spi/core.c
> @@ -894,6 +894,7 @@ static const struct nand_ops spinand_ops = {
>  };
>  
>  static const struct spinand_manufacturer *spinand_manufacturers[] = {
> +	&etron_spinand_manufacturer,
>  	&gigadevice_spinand_manufacturer,
>  	&macronix_spinand_manufacturer,
>  	&micron_spinand_manufacturer,
> diff --git a/drivers/mtd/nand/spi/etron.c b/drivers/mtd/nand/spi/etron.c
> new file mode 100644
> index 000000000000..1a92b9cf3043
> --- /dev/null
> +++ b/drivers/mtd/nand/spi/etron.c
> @@ -0,0 +1,104 @@
> +// SPDX-License-Identifier: GPL-2.0
> +
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/mtd/spinand.h>
> +
> +#define SPINAND_MFR_ETRON			0xd5
> +
> +static SPINAND_OP_VARIANTS(read_cache_variants,
> +		SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_X4_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_X2_OP(0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_OP(true, 0, 1, NULL, 0),
> +		SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(write_cache_variants,
> +		SPINAND_PROG_LOAD_X4(true, 0, NULL, 0),
> +		SPINAND_PROG_LOAD(true, 0, NULL, 0));
> +
> +static SPINAND_OP_VARIANTS(update_cache_variants,
> +		SPINAND_PROG_LOAD_X4(false, 0, NULL, 0),
> +		SPINAND_PROG_LOAD(false, 0, NULL, 0));
> +
> +static int etron_oob_spare(struct mtd_info *mtd)
> +{
> +	if (mtd->size < 0x10000000)
> +		return mtd->oobsize / 2;
> +	else
> +		return mtd->oobsize / 2 + mtd->oobsize / 16;
> +}
> +
> +static int etron_ooblayout_ecc(struct mtd_info *mtd, int section,
> +					struct mtd_oob_region *oobregion)
> +{
> +	if (section)
> +		return -ERANGE;
> +
> +	oobregion->offset = etron_oob_spare(mtd);
> +	oobregion->length = mtd->oobsize - oobregion->offset;
> +
> +	return 0;
> +}
> +
> +static int etron_ooblayout_free(struct mtd_info *mtd, int section,
> +			   struct mtd_oob_region *oobregion)
> +{
> +	if (section)
> +		return -ERANGE;
> +
> +	oobregion->offset = 2;
> +	oobregion->length = etron_oob_spare(mtd) - 2;
> +
> +	return 0;
> +}
> +
> +static const struct mtd_ooblayout_ops etron_ooblayout = {
> +	.ecc = etron_ooblayout_ecc,
> +	.free = etron_ooblayout_free,
> +};
> +
> +static int etron_ecc_get_status(struct spinand_device *spinand, u8 status)
> +{
> +	switch (status & STATUS_ECC_MASK) {
> +	case STATUS_ECC_NO_BITFLIPS:
> +		return 0;
> +
> +	case STATUS_ECC_HAS_BITFLIPS:
> +		/* Between 1-7 bitflips were corrected */
> +		return 7;
> +
> +	case STATUS_ECC_MASK:

I'm not sure if using STATUS_ECC_MASK here to check for the 0b11 pattern
is really a good idea. I'd rather introduce a vendor-specific define for
this as other drivers do (see toshiba.c, paragon.c or gigadevice.c). As
this seems to be a common pattern among vendors we could also think
about introducing a new common flag like STATUS_ECC_HAS_MAX_BITFLIPS or
something like that and use this instead.

> +		/* Maximum bitflips were corrected */
> +		return 8;
> +
> +	case STATUS_ECC_UNCOR_ERROR:
> +		return -EBADMSG;
> +	}
> +
> +	return -EINVAL;
> +}
> +
> +static const struct spinand_info etron_spinand_table[] = {
> +	SPINAND_INFO("EM73D044VCx",
> +		     SPINAND_ID(SPINAND_READID_METHOD_OPCODE_ADDR, 0x1f),

According to the datasheet, the device id of the EM73D044VCL is 0x2e and
not 0x1f. Am I missing something?

Best regards
Frieder

> +		     NAND_MEMORG(1, 2048, 128, 64, 2048, 40, 1, 1, 1),
> +		     NAND_ECCREQ(8, 512),
> +		     SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
> +					      &write_cache_variants,
> +					      &update_cache_variants),
> +		     SPINAND_HAS_QE_BIT,
> +		     SPINAND_ECCINFO(&etron_ooblayout, etron_ecc_get_status)),
> +};
> +
> +static const struct spinand_manufacturer_ops etron_spinand_manuf_ops = {
> +};
> +
> +const struct spinand_manufacturer etron_spinand_manufacturer = {
> +	.id = SPINAND_MFR_ETRON,
> +	.name = "Etron",
> +	.chips = etron_spinand_table,
> +	.nchips = ARRAY_SIZE(etron_spinand_table),
> +	.ops = &etron_spinand_manuf_ops,
> +};
> diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
> index 6988956b8492..d7c0a0439652 100644
> --- a/include/linux/mtd/spinand.h
> +++ b/include/linux/mtd/spinand.h
> @@ -260,6 +260,7 @@ struct spinand_manufacturer {
>  };
>  
>  /* SPI NAND manufacturers */
> +extern const struct spinand_manufacturer etron_spinand_manufacturer;
>  extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
>  extern const struct spinand_manufacturer macronix_spinand_manufacturer;
>  extern const struct spinand_manufacturer micron_spinand_manufacturer;
> 

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

end of thread, other threads:[~2021-09-15  8:13 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-08 20:16 [PATCH v2] mtd: spinand: Add support for Etron EM73D044VCx Bert Vermeulen
2021-09-14 17:31 ` Miquel Raynal
2021-09-14 17:49   ` Richard Weinberger
2021-09-14 20:03     ` Bert Vermeulen
2021-09-15  7:13       ` Miquel Raynal
2021-09-15  8:13 ` Frieder Schrempf

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).