* [PATCH v3] mtd: spinand: Add support for AllianceMemory AS5F34G04SND
@ 2023-01-25 12:22 Mario Kicherer
2023-01-26 9:07 ` Miquel Raynal
0 siblings, 1 reply; 2+ messages in thread
From: Mario Kicherer @ 2023-01-25 12:22 UTC (permalink / raw)
To: linux-mtd; +Cc: miquel.raynal, richard, vigneshr, Mario Kicherer, Dhruva Gole
Add support for AllianceMemory AS5F34G04SND SPI NAND flash
Datasheet:
- https://www.alliancememory.com/wp-content/uploads/pdf/flash/AllianceMemory_SPI_NAND_Flash_July2020_Rev1.0.pdf
Signed-off-by: Mario Kicherer <dev@kicherer.org>
Reviewed-by: Dhruva Gole <d-gole@ti.com>
---
drivers/mtd/nand/spi/Makefile | 2 +-
drivers/mtd/nand/spi/alliancememory.c | 110 ++++++++++++++++++++++++++
drivers/mtd/nand/spi/core.c | 1 +
include/linux/mtd/spinand.h | 1 +
4 files changed, 113 insertions(+), 1 deletion(-)
create mode 100644 drivers/mtd/nand/spi/alliancememory.c
diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
index b520fe634041..4ec973b8b6bf 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 ato.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
+spinand-objs := core.o alliancememory.o ato.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
diff --git a/drivers/mtd/nand/spi/alliancememory.c b/drivers/mtd/nand/spi/alliancememory.c
new file mode 100644
index 000000000000..3430ac4d18fc
--- /dev/null
+++ b/drivers/mtd/nand/spi/alliancememory.c
@@ -0,0 +1,110 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Author: Mario Kicherer <dev@kicherer.org>
+ */
+
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/mtd/spinand.h>
+
+#define SPINAND_MFR_ALLIANCEMEMORY 0x52
+
+#define AM_STATUS_ECC_BITMASK (3 << 4)
+
+#define AM_STATUS_ECC_NONE_DETECTED (0 << 4)
+#define AM_STATUS_ECC_1_CORRECTED (1 << 4)
+#define AM_STATUS_ECC_1_DETECTED (2 << 4)
+#define AM_STATUS_ECC_MAX_CORRECTED (3 << 4)
+
+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 as5f34g04snd_ooblayout_ecc(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ region->offset = 0x48;
+ region->length = 0x38;
+
+ return 0;
+}
+
+static int as5f34g04snd_ooblayout_free(struct mtd_info *mtd, int section,
+ struct mtd_oob_region *region)
+{
+ if (section)
+ return -ERANGE;
+
+ /*
+ * It is unclear how many bytes are used for the bad block marker. We
+ * reserve the common two bytes here.
+ */
+
+ region->offset = 2;
+ region->length = 0x48 - 2;
+
+ return 0;
+}
+
+static const struct mtd_ooblayout_ops as5f34g04snd_ooblayout = {
+ .ecc = as5f34g04snd_ooblayout_ecc,
+ .free = as5f34g04snd_ooblayout_free,
+};
+
+static int am_ecc_get_status(struct spinand_device *spinand, u8 status)
+{
+ switch (status & AM_STATUS_ECC_BITMASK) {
+ case AM_STATUS_ECC_NONE_DETECTED:
+ return 0;
+
+ case AM_STATUS_ECC_1_CORRECTED:
+ return 1;
+
+ case AM_STATUS_ECC_MAX_CORRECTED:
+ return 8;
+
+ case AM_STATUS_ECC_1_DETECTED:
+ return -EBADMSG;
+
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static const struct spinand_info alliancememory_spinand_table[] = {
+ SPINAND_INFO("AS5F34G04SND",
+ SPINAND_ID(SPINAND_READID_METHOD_OPCODE_DUMMY, 0x2f),
+ NAND_MEMORG(1, 2048, 128, 64, 4096, 80, 1, 1, 1),
+ NAND_ECCREQ(4, 512),
+ SPINAND_INFO_OP_VARIANTS(&read_cache_variants,
+ &write_cache_variants,
+ &update_cache_variants),
+ SPINAND_HAS_QE_BIT,
+ SPINAND_ECCINFO(&as5f34g04snd_ooblayout,
+ am_ecc_get_status)),
+};
+
+static const struct spinand_manufacturer_ops alliancememory_spinand_manuf_ops = {
+};
+
+const struct spinand_manufacturer alliancememory_spinand_manufacturer = {
+ .id = SPINAND_MFR_ALLIANCEMEMORY,
+ .name = "AllianceMemory",
+ .chips = alliancememory_spinand_table,
+ .nchips = ARRAY_SIZE(alliancememory_spinand_table),
+ .ops = &alliancememory_spinand_manuf_ops,
+};
diff --git a/drivers/mtd/nand/spi/core.c b/drivers/mtd/nand/spi/core.c
index dacd9c0e8b20..638391f77d8c 100644
--- a/drivers/mtd/nand/spi/core.c
+++ b/drivers/mtd/nand/spi/core.c
@@ -937,6 +937,7 @@ static const struct nand_ops spinand_ops = {
};
static const struct spinand_manufacturer *spinand_manufacturers[] = {
+ &alliancememory_spinand_manufacturer,
&ato_spinand_manufacturer,
&gigadevice_spinand_manufacturer,
¯onix_spinand_manufacturer,
diff --git a/include/linux/mtd/spinand.h b/include/linux/mtd/spinand.h
index 6d3392a7edc6..01be9f0f008a 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 alliancememory_spinand_manufacturer;
extern const struct spinand_manufacturer ato_spinand_manufacturer;
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
--
2.34.1
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v3] mtd: spinand: Add support for AllianceMemory AS5F34G04SND
2023-01-25 12:22 [PATCH v3] mtd: spinand: Add support for AllianceMemory AS5F34G04SND Mario Kicherer
@ 2023-01-26 9:07 ` Miquel Raynal
0 siblings, 0 replies; 2+ messages in thread
From: Miquel Raynal @ 2023-01-26 9:07 UTC (permalink / raw)
To: Mario Kicherer; +Cc: linux-mtd, richard, vigneshr, Dhruva Gole
Hi Mario,
dev@kicherer.org wrote on Wed, 25 Jan 2023 13:22:04 +0100:
> Add support for AllianceMemory AS5F34G04SND SPI NAND flash
>
> Datasheet:
> - https://www.alliancememory.com/wp-content/uploads/pdf/flash/AllianceMemory_SPI_NAND_Flash_July2020_Rev1.0.pdf
>
> Signed-off-by: Mario Kicherer <dev@kicherer.org>
> Reviewed-by: Dhruva Gole <d-gole@ti.com>
> ---
> drivers/mtd/nand/spi/Makefile | 2 +-
> drivers/mtd/nand/spi/alliancememory.c | 110 ++++++++++++++++++++++++++
> drivers/mtd/nand/spi/core.c | 1 +
> include/linux/mtd/spinand.h | 1 +
> 4 files changed, 113 insertions(+), 1 deletion(-)
> create mode 100644 drivers/mtd/nand/spi/alliancememory.c
>
> diff --git a/drivers/mtd/nand/spi/Makefile b/drivers/mtd/nand/spi/Makefile
> index b520fe634041..4ec973b8b6bf 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 ato.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
> +spinand-objs := core.o alliancememory.o ato.o gigadevice.o macronix.o micron.o paragon.o toshiba.o winbond.o xtx.o
> obj-$(CONFIG_MTD_SPI_NAND) += spinand.o
> diff --git a/drivers/mtd/nand/spi/alliancememory.c b/drivers/mtd/nand/spi/alliancememory.c
> new file mode 100644
> index 000000000000..3430ac4d18fc
> --- /dev/null
> +++ b/drivers/mtd/nand/spi/alliancememory.c
> @@ -0,0 +1,110 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Author: Mario Kicherer <dev@kicherer.org>
> + */
> +
> +#include <linux/device.h>
> +#include <linux/kernel.h>
> +#include <linux/mtd/spinand.h>
> +
> +#define SPINAND_MFR_ALLIANCEMEMORY 0x52
> +
> +#define AM_STATUS_ECC_BITMASK (3 << 4)
> +
> +#define AM_STATUS_ECC_NONE_DETECTED (0 << 4)
> +#define AM_STATUS_ECC_1_CORRECTED (1 << 4)
> +#define AM_STATUS_ECC_1_DETECTED (2 << 4)
> +#define AM_STATUS_ECC_MAX_CORRECTED (3 << 4)
> +
> +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 as5f34g04snd_ooblayout_ecc(struct mtd_info *mtd, int section,
> + struct mtd_oob_region *region)
> +{
> + region->offset = 0x48;
> + region->length = 0x38;
This NAND series uses the end of the oob area to store the ecc bytes.
You can just hardcode how much ECC bytes are used because that's only
what matters and do something more readable:
ecc_bytes = [32 if page is 2k and OOB 64B] || [56 if page is 2k and OOB
is 128B] || [112 if page is 4k and OOB 256]
offset = mtd->oobsize - ecc_bytes
length = ecc_bytes
> +
> + return 0;
> +}
> +
> +static int as5f34g04snd_ooblayout_free(struct mtd_info *mtd, int section,
> + struct mtd_oob_region *region)
> +{
> + if (section)
> + return -ERANGE;
> +
> + /*
> + * It is unclear how many bytes are used for the bad block marker. We
> + * reserve the common two bytes here.
> + */
You could maybe indicate in the comment that the free area is made of
sequential 4 or 8 identical chunks where each first 4 bytes are
unprotected.
> +
> + region->offset = 2;
> + region->length = 0x48 - 2;
And here again:
offset = 2
length = mtd->oobsize - 2 - ecc_bytes
> +
> + return 0;
> +}
Thanks,
Miquèl
______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2023-01-26 9:07 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-01-25 12:22 [PATCH v3] mtd: spinand: Add support for AllianceMemory AS5F34G04SND Mario Kicherer
2023-01-26 9:07 ` Miquel Raynal
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox