linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g
@ 2022-02-09 13:36 Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name Tudor Ambarus
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

Hi,

I've made some core work as a prerequisite for mx66lm1g45g addition.
I've cleaned the RDID op and the flash detection. I introduced
SPI_NOR_READID_OP to ease the spi_mem_op filling. I would like to
follow the idea and introduce macros for all the SPI NOR ops, but
after we'll integrate Michael's SR patches.

Cheers,
ta

v6: complete rework

Tudor Ambarus (7):
  mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name
  mtd: spi-nor: Introduce spi_nor_match_id()
  mtd: spi-nor: core: Use auto-detection only once
  mtd: spi-nor: core: Introduce method for RDID op
  mtd: spi-nor: manufacturers: Use spi_nor_read_id() core method
  mtd: spi-nor: core: Introduce SPI_NOR_SOFT_RESET flash_info fixup_flag
  mtd: spi-nor: macronix: Add support for mx66lm1g45g

 drivers/mtd/spi-nor/core.c      | 115 +++++++++++++++++-----------
 drivers/mtd/spi-nor/core.h      |  14 ++++
 drivers/mtd/spi-nor/macronix.c  | 131 ++++++++++++++++++++++++++++++++
 drivers/mtd/spi-nor/micron-st.c |  13 +---
 drivers/mtd/spi-nor/spansion.c  |  13 +---
 5 files changed, 221 insertions(+), 65 deletions(-)

-- 
2.25.1


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

* [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name
  2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
@ 2022-02-09 13:36 ` Tudor Ambarus
  2022-03-21 11:53   ` Pratyush Yadav
  2022-02-09 13:36 ` [PATCH v6 2/7] mtd: spi-nor: Introduce spi_nor_match_id() Tudor Ambarus
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

The method is matching a flash_info entry by searching by name. Rename
the method for better clarity.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/core.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 04ea180118e3..345f9da96fab 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3109,8 +3109,8 @@ void spi_nor_restore(struct spi_nor *nor)
 }
 EXPORT_SYMBOL_GPL(spi_nor_restore);
 
-static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
-						 const char *name)
+static const struct flash_info *spi_nor_match_name(struct spi_nor *nor,
+						   const char *name)
 {
 	unsigned int i, j;
 
@@ -3132,7 +3132,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 	const struct flash_info *info = NULL;
 
 	if (name)
-		info = spi_nor_match_id(nor, name);
+		info = spi_nor_match_name(nor, name);
 	/* Try to auto-detect if chip name wasn't specified or not found */
 	if (!info)
 		info = spi_nor_read_id(nor);
-- 
2.25.1


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

* [PATCH v6 2/7] mtd: spi-nor: Introduce spi_nor_match_id()
  2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name Tudor Ambarus
@ 2022-02-09 13:36 ` Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 3/7] mtd: spi-nor: core: Use auto-detection only once Tudor Ambarus
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

Similar to spi_nor_match_name() extend the search of flash_info through
all the manufacturers, this time doing the match by ID. There's no reason
to limit the search per manufacturer yet, do it globally, search the flash
in all the parts of all manufacturers in a single method.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/core.c | 40 ++++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 21 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 345f9da96fab..335170fc2438 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -1848,16 +1848,21 @@ static const struct spi_nor_manufacturer *manufacturers[] = {
 	&spi_nor_xmc,
 };
 
-static const struct flash_info *
-spi_nor_search_part_by_id(const struct flash_info *parts, unsigned int nparts,
-			  const u8 *id)
+static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
+						 const u8 *id)
 {
-	unsigned int i;
+	const struct flash_info *part;
+	unsigned int i, j;
 
-	for (i = 0; i < nparts; i++) {
-		if (parts[i].id_len &&
-		    !memcmp(parts[i].id, id, parts[i].id_len))
-			return &parts[i];
+	for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
+		for (j = 0; j < manufacturers[i]->nparts; j++) {
+			part = &manufacturers[i]->parts[j];
+			if (part->id_len &&
+			    !memcmp(part->id, id, part->id_len)) {
+				nor->manufacturer = manufacturers[i];
+				return part;
+			}
+		}
 	}
 
 	return NULL;
@@ -1867,7 +1872,6 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
 {
 	const struct flash_info *info;
 	u8 *id = nor->bouncebuf;
-	unsigned int i;
 	int ret;
 
 	if (nor->spimem) {
@@ -1887,19 +1891,13 @@ static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
 		return ERR_PTR(ret);
 	}
 
-	for (i = 0; i < ARRAY_SIZE(manufacturers); i++) {
-		info = spi_nor_search_part_by_id(manufacturers[i]->parts,
-						 manufacturers[i]->nparts,
-						 id);
-		if (info) {
-			nor->manufacturer = manufacturers[i];
-			return info;
-		}
+	info = spi_nor_match_id(nor, id);
+	if (!info) {
+		dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
+			SPI_NOR_MAX_ID_LEN, id);
+		return ERR_PTR(-ENODEV);
 	}
-
-	dev_err(nor->dev, "unrecognized JEDEC id bytes: %*ph\n",
-		SPI_NOR_MAX_ID_LEN, id);
-	return ERR_PTR(-ENODEV);
+	return info;
 }
 
 static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
-- 
2.25.1


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

* [PATCH v6 3/7] mtd: spi-nor: core: Use auto-detection only once
  2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 2/7] mtd: spi-nor: Introduce spi_nor_match_id() Tudor Ambarus
@ 2022-02-09 13:36 ` Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 4/7] mtd: spi-nor: core: Introduce method for RDID op Tudor Ambarus
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

In case spi_nor_match_name() returned NULL, the auto detection was
issued twice. There's no reason to try to detect the same chip twice,
do the auto detection only once.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/core.c | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 335170fc2438..9b740f77174e 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -3127,13 +3127,15 @@ static const struct flash_info *spi_nor_match_name(struct spi_nor *nor,
 static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 						       const char *name)
 {
-	const struct flash_info *info = NULL;
+	const struct flash_info *info = NULL, *detected_info = NULL;
 
 	if (name)
 		info = spi_nor_match_name(nor, name);
 	/* Try to auto-detect if chip name wasn't specified or not found */
-	if (!info)
-		info = spi_nor_read_id(nor);
+	if (!info) {
+		detected_info = spi_nor_read_id(nor);
+		info = detected_info;
+	}
 	if (IS_ERR_OR_NULL(info))
 		return ERR_PTR(-ENOENT);
 
@@ -3141,7 +3143,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 	 * If caller has specified name of flash model that can normally be
 	 * detected using JEDEC, let's verify it.
 	 */
-	if (name && info->id_len) {
+	if (name && !detected_info && info->id_len) {
 		const struct flash_info *jinfo;
 
 		jinfo = spi_nor_read_id(nor);
-- 
2.25.1


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

* [PATCH v6 4/7] mtd: spi-nor: core: Introduce method for RDID op
  2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
                   ` (2 preceding siblings ...)
  2022-02-09 13:36 ` [PATCH v6 3/7] mtd: spi-nor: core: Use auto-detection only once Tudor Ambarus
@ 2022-02-09 13:36 ` Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 5/7] mtd: spi-nor: manufacturers: Use spi_nor_read_id() core method Tudor Ambarus
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

RDID is used in the core to auto detect the flash, but also by some
manufacturer drivers that contain flashes that support Octal DTR mode,
so that they can read the flash ID after the switch to Octal DTR was made
to test if the switch was successful. Introduce a core method for RDID op
to avoid code duplication.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/core.c | 58 ++++++++++++++++++++++++++------------
 drivers/mtd/spi-nor/core.h | 11 ++++++++
 2 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 9b740f77174e..35280994a179 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -369,6 +369,41 @@ int spi_nor_write_disable(struct spi_nor *nor)
 	return ret;
 }
 
+/**
+ * spi_nor_read_id() - Read the JEDEC ID.
+ * @nor:	pointer to 'struct spi_nor'.
+ * @naddr:	number of address bytes to send. Can be zero if the operation
+ *		does not need to send an address.
+ * @ndummy:	number of dummy bytes to send after an opcode or address. Can
+ *		be zero if the operation does not require dummy bytes.
+ * @id:		pointer to a DMA-able buffer where the value of the JEDEC ID
+ *		will be written.
+ * @reg_proto:	the SPI protocol for register operation.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
+		    enum spi_nor_protocol reg_proto)
+{
+	int ret;
+
+	if (nor->spimem) {
+		struct spi_mem_op op = SPI_NOR_READID_OP(
+			naddr, ndummy, id, SPI_NOR_MAX_ID_LEN);
+
+		spi_nor_spimem_setup_op(nor, &op, reg_proto);
+		ret = spi_mem_exec_op(nor->spimem, &op);
+	} else {
+		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id,
+						    SPI_NOR_MAX_ID_LEN);
+	}
+
+	if (ret)
+		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", ret);
+
+	return ret;
+}
+
 /**
  * spi_nor_read_sr() - Read the Status Register.
  * @nor:	pointer to 'struct spi_nor'.
@@ -1868,28 +1903,15 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
 	return NULL;
 }
 
-static const struct flash_info *spi_nor_read_id(struct spi_nor *nor)
+static const struct flash_info *spi_nor_detect(struct spi_nor *nor)
 {
 	const struct flash_info *info;
 	u8 *id = nor->bouncebuf;
 	int ret;
 
-	if (nor->spimem) {
-		struct spi_mem_op op =
-			SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
-				   SPI_MEM_OP_NO_ADDR,
-				   SPI_MEM_OP_NO_DUMMY,
-				   SPI_MEM_OP_DATA_IN(SPI_NOR_MAX_ID_LEN, id, 1));
-
-		ret = spi_mem_exec_op(nor->spimem, &op);
-	} else {
-		ret = nor->controller_ops->read_reg(nor, SPINOR_OP_RDID, id,
-						    SPI_NOR_MAX_ID_LEN);
-	}
-	if (ret) {
-		dev_dbg(nor->dev, "error %d reading JEDEC ID\n", ret);
+	ret = spi_nor_read_id(nor, 0, 0, id, nor->reg_proto);
+	if (ret)
 		return ERR_PTR(ret);
-	}
 
 	info = spi_nor_match_id(nor, id);
 	if (!info) {
@@ -3133,7 +3155,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 		info = spi_nor_match_name(nor, name);
 	/* Try to auto-detect if chip name wasn't specified or not found */
 	if (!info) {
-		detected_info = spi_nor_read_id(nor);
+		detected_info = spi_nor_detect(nor);
 		info = detected_info;
 	}
 	if (IS_ERR_OR_NULL(info))
@@ -3146,7 +3168,7 @@ static const struct flash_info *spi_nor_get_flash_info(struct spi_nor *nor,
 	if (name && !detected_info && info->id_len) {
 		const struct flash_info *jinfo;
 
-		jinfo = spi_nor_read_id(nor);
+		jinfo = spi_nor_detect(nor);
 		if (IS_ERR(jinfo)) {
 			return jinfo;
 		} else if (jinfo != info) {
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 2afb610853a9..04d4cc13d13b 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -11,6 +11,15 @@
 
 #define SPI_NOR_MAX_ID_LEN	6
 
+/**
+ * Standard SPI NOR flash operations.
+ */
+#define SPI_NOR_READID_OP(naddr, ndummy, buf, len)			\
+	SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 0),			\
+		   SPI_MEM_OP_ADDR(naddr, 0, 0),			\
+		   SPI_MEM_OP_DUMMY(ndummy, 0),				\
+		   SPI_MEM_OP_DATA_IN(len, buf, 0))
+
 enum spi_nor_option_flags {
 	SNOR_F_USE_FSR		= BIT(0),
 	SNOR_F_HAS_SR_TB	= BIT(1),
@@ -553,6 +562,8 @@ void spi_nor_unlock_and_unprep(struct spi_nor *nor);
 int spi_nor_sr1_bit6_quad_enable(struct spi_nor *nor);
 int spi_nor_sr2_bit1_quad_enable(struct spi_nor *nor);
 int spi_nor_sr2_bit7_quad_enable(struct spi_nor *nor);
+int spi_nor_read_id(struct spi_nor *nor, u8 naddr, u8 ndummy, u8 *id,
+		    enum spi_nor_protocol reg_proto);
 int spi_nor_read_sr(struct spi_nor *nor, u8 *sr);
 int spi_nor_read_cr(struct spi_nor *nor, u8 *cr);
 int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len);
-- 
2.25.1


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

* [PATCH v6 5/7] mtd: spi-nor: manufacturers: Use spi_nor_read_id() core method
  2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
                   ` (3 preceding siblings ...)
  2022-02-09 13:36 ` [PATCH v6 4/7] mtd: spi-nor: core: Introduce method for RDID op Tudor Ambarus
@ 2022-02-09 13:36 ` Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 6/7] mtd: spi-nor: core: Introduce SPI_NOR_SOFT_RESET flash_info fixup_flag Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 7/7] mtd: spi-nor: macronix: Add support for mx66lm1g45g Tudor Ambarus
  6 siblings, 0 replies; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

Use spi_nor_read_id() core method to avoid duplication of code. Now the ID
is read on the full SPI_NOR_MAX_ID_LEN instead of
round_up(nor->info->id_len, 2), but it doesn't harm to read more ID bytes,
so the change comes with no secondary effects.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
 drivers/mtd/spi-nor/micron-st.c | 13 +++----------
 drivers/mtd/spi-nor/spansion.c  | 13 +++----------
 2 files changed, 6 insertions(+), 20 deletions(-)

diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index bb95b1aabf74..7f66b5943ceb 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -80,17 +80,10 @@ static int spi_nor_micron_octal_dtr_enable(struct spi_nor *nor, bool enable)
 		return ret;
 
 	/* Read flash ID to make sure the switch was successful. */
-	op = (struct spi_mem_op)
-		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
-			   SPI_MEM_OP_NO_ADDR,
-			   SPI_MEM_OP_DUMMY(enable ? 8 : 0, 1),
-			   SPI_MEM_OP_DATA_IN(round_up(nor->info->id_len, 2),
-					      buf, 1));
-
 	if (enable)
-		spi_nor_spimem_setup_op(nor, &op, SNOR_PROTO_8_8_8_DTR);
-
-	ret = spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_nor_read_id(nor, 0, 8, buf, SNOR_PROTO_8_8_8_DTR);
+	else
+		ret = spi_nor_read_id(nor, 0, 0, buf, nor->reg_proto);
 	if (ret)
 		return ret;
 
diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c
index 534196b1d3e7..d69a569f31e4 100644
--- a/drivers/mtd/spi-nor/spansion.c
+++ b/drivers/mtd/spi-nor/spansion.c
@@ -94,17 +94,10 @@ static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor, bool enable)
 		return ret;
 
 	/* Read flash ID to make sure the switch was successful. */
-	op = (struct spi_mem_op)
-		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RDID, 1),
-			   SPI_MEM_OP_ADDR(enable ? 4 : 0, 0, 1),
-			   SPI_MEM_OP_DUMMY(enable ? 3 : 0, 1),
-			   SPI_MEM_OP_DATA_IN(round_up(nor->info->id_len, 2),
-					      buf, 1));
-
 	if (enable)
-		spi_nor_spimem_setup_op(nor, &op, SNOR_PROTO_8_8_8_DTR);
-
-	ret = spi_mem_exec_op(nor->spimem, &op);
+		ret = spi_nor_read_id(nor, 4, 3, buf, SNOR_PROTO_8_8_8_DTR);
+	else
+		ret = spi_nor_read_id(nor, 0, 0, buf, nor->reg_proto);
 	if (ret)
 		return ret;
 
-- 
2.25.1


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

* [PATCH v6 6/7] mtd: spi-nor: core: Introduce SPI_NOR_SOFT_RESET flash_info fixup_flag
  2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
                   ` (4 preceding siblings ...)
  2022-02-09 13:36 ` [PATCH v6 5/7] mtd: spi-nor: manufacturers: Use spi_nor_read_id() core method Tudor Ambarus
@ 2022-02-09 13:36 ` Tudor Ambarus
  2022-02-09 13:36 ` [PATCH v6 7/7] mtd: spi-nor: macronix: Add support for mx66lm1g45g Tudor Ambarus
  6 siblings, 0 replies; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

The Soft Reset and Rescue Sequence Support is defined in BFPT_DWORD(16)
starting with JESD216A. The first version of SFDP, JESD216 (April 2011),
defines just the first 9 BFPT DWORDS, thus it does not contain information
about the Software Reset and Rescue Support. Since this support can not
be discovered by parsing the first SFDP version, introduce a flash_info
fixup_flag that will be used either by flashes that define
JESD216 (April 2011) or by flashes that do not define SFDP at all.
In case a flash defines BFPT_DWORD(16) but with wrong values, one should
instead use a post_bfpt() hook and set SNOR_F_SOFT_RESET.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
---
 drivers/mtd/spi-nor/core.c | 3 +++
 drivers/mtd/spi-nor/core.h | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index 35280994a179..7d5e3acb0ae7 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2719,6 +2719,9 @@ static void spi_nor_init_fixup_flags(struct spi_nor *nor)
 
 	if (fixup_flags & SPI_NOR_IO_MODE_EN_VOLATILE)
 		nor->flags |= SNOR_F_IO_MODE_EN_VOLATILE;
+
+	if (fixup_flags & SPI_NOR_SOFT_RESET)
+		nor->flags |= SNOR_F_SOFT_RESET;
 }
 
 /**
diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
index 04d4cc13d13b..cbfb4fa7647f 100644
--- a/drivers/mtd/spi-nor/core.h
+++ b/drivers/mtd/spi-nor/core.h
@@ -382,6 +382,8 @@ struct spi_nor_fixups {
  *                            memory size above 128Mib.
  *   SPI_NOR_IO_MODE_EN_VOLATILE: flash enables the best available I/O mode
  *                            via a volatile bit.
+ *   SPI_NOR_SOFT_RESET:      flash supports software reset enable, reset
+ *                            sequence.
  * @mfr_flags:      manufacturer private flags. Used in the manufacturer fixup
  *                  hooks to differentiate support between flashes of the same
  *                  manufacturer.
@@ -425,6 +427,7 @@ struct flash_info {
 	u8 fixup_flags;
 #define SPI_NOR_4B_OPCODES		BIT(0)
 #define SPI_NOR_IO_MODE_EN_VOLATILE	BIT(1)
+#define SPI_NOR_SOFT_RESET		BIT(2)
 
 	u8 mfr_flags;
 
-- 
2.25.1


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

* [PATCH v6 7/7] mtd: spi-nor: macronix: Add support for mx66lm1g45g
  2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
                   ` (5 preceding siblings ...)
  2022-02-09 13:36 ` [PATCH v6 6/7] mtd: spi-nor: core: Introduce SPI_NOR_SOFT_RESET flash_info fixup_flag Tudor Ambarus
@ 2022-02-09 13:36 ` Tudor Ambarus
  6 siblings, 0 replies; 10+ messages in thread
From: Tudor Ambarus @ 2022-02-09 13:36 UTC (permalink / raw)
  To: p.yadav, michael
  Cc: miquel.raynal, richard, vigneshr, linux-mtd, linux-kernel,
	nicolas.ferre, zhengxunli, jaimeliao, Tudor Ambarus

mx66lm1g45g supports just 1-1-1, 8-8-8 and 8D-8D-8D modes. There are
versions of mx66lm1g45g which do not support SFDP, thus use
SPI_NOR_SKIP_SFDP. The RDID command issued through the octal peripheral
interface outputs data always in STR mode for whatever reason. Since
8D-8D-8S is not common, avoid reading the ID when enabling the octal dtr
mode. Instead, read back the CR2 to check if the switch was successful.
Tested in 1-1-1 and 8d-8d-8d modes using sama7g5 QSPI IP.

Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
---
# cat /sys/devices/platform/soc/e080c000.spi/spi_master/spi1/spi1.0/spi-nor/jedec_id
c2853b
# cat /sys/devices/platform/soc/e080c000.spi/spi_master/spi1/spi1.0/spi-nor/manufacturer
macronix
# cat /sys/devices/platform/soc/e080c000.spi/spi_master/spi1/spi1.0/spi-nor/partname
mx66lm1g45g
# cat /sys/devices/platform/soc/e080c000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp
cat: can't open '/sys/devices/platform/soc/e080c000.spi/spi_master/spi1/spi1.0/spi-nor/sfdp': No such file or directory

 drivers/mtd/spi-nor/macronix.c | 131 +++++++++++++++++++++++++++++++++
 1 file changed, 131 insertions(+)

diff --git a/drivers/mtd/spi-nor/macronix.c b/drivers/mtd/spi-nor/macronix.c
index 97dba1ae7fb1..31b2a9f34e03 100644
--- a/drivers/mtd/spi-nor/macronix.c
+++ b/drivers/mtd/spi-nor/macronix.c
@@ -8,6 +8,130 @@
 
 #include "core.h"
 
+#define SPINOR_OP_READ_CR2		0x71	/* Read Configuration Register 2 */
+#define SPINOR_OP_WRITE_CR2		0x72	/* Write Configuration Register 2 */
+#define SPINOR_OP_MX_DTR_RD		0xee	/* Octa DTR Read Opcode */
+
+#define SPINOR_REG_CR2_MODE_ADDR	0	/* Address of Mode Enable in CR2 */
+#define SPINOR_REG_CR2_DTR_OPI_ENABLE	BIT(1)	/* DTR OPI Enable */
+#define SPINOR_REG_CR2_SPI		0	/* SPI Enable */
+
+/**
+ * Macronix SPI NOR flash operations.
+ */
+#define SPI_NOR_MX_READ_CR2_OP(ndummy, buf, ndata)			\
+	SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_READ_CR2, 0),		\
+		   SPI_MEM_OP_ADDR(4, SPINOR_REG_CR2_MODE_ADDR, 0),	\
+		   SPI_MEM_OP_DUMMY(ndummy, 0),				\
+		   SPI_MEM_OP_DATA_IN(ndata, buf, 0))
+
+#define SPI_NOR_MX_WRITE_CR2_OP(buf, ndata)				\
+	SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRITE_CR2, 0),		\
+		   SPI_MEM_OP_ADDR(4, SPINOR_REG_CR2_MODE_ADDR, 0),	\
+		   SPI_MEM_OP_NO_DUMMY,					\
+		   SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
+
+static int spi_nor_macronix_read_cr2(struct spi_nor *nor, u8 ndummy, void *sr,
+				     unsigned int nbytes)
+{
+	struct spi_mem_op op = SPI_NOR_MX_READ_CR2_OP(ndummy, sr, nbytes);
+
+	spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+	return spi_mem_exec_op(nor->spimem, &op);
+}
+
+static int spi_nor_macronix_write_cr2(struct spi_nor *nor, const void *sr,
+				      unsigned int nbytes)
+{
+	struct spi_mem_op op = SPI_NOR_MX_WRITE_CR2_OP(sr, nbytes);
+	int ret;
+
+	spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
+	ret = spi_nor_write_enable(nor);
+	if (ret)
+		return ret;
+	return spi_mem_exec_op(nor->spimem, &op);
+}
+
+static int spi_nor_macronix_octal_dtr_en(struct spi_nor *nor)
+{
+	u8 *buf = nor->bouncebuf;
+	int i, ret;
+
+	buf[0] = SPINOR_REG_CR2_DTR_OPI_ENABLE;
+	ret = spi_nor_macronix_write_cr2(nor, buf, 1);
+	if (ret)
+		return ret;
+
+	/* Read flash ID to make sure the switch was successful. */
+	ret = spi_nor_read_id(nor, 4, 4, buf, SNOR_PROTO_8_8_8_DTR);
+	if (ret)
+		return ret;
+
+	for (i = 0; i < nor->info->id_len; i++)
+		if (buf[i * 2] != nor->info->id[i])
+			return -EINVAL;
+	return 0;
+}
+
+static int spi_nor_macronix_octal_dtr_dis(struct spi_nor *nor)
+{
+	u8 *buf = nor->bouncebuf;
+	int ret;
+
+	/*
+	 * One byte transactions are not allowed in 8D-8D-8D mode. mx66lm1g45g
+	 * requires that undefined register addresses to keep their value
+	 * unchanged. Its second CR2 byte value is not defined. Read the second
+	 * byte value of CR2 so that we can write it back when disabling
+	 * Octal DTR mode.
+	 */
+	ret = spi_nor_macronix_read_cr2(nor, 4, buf, 2);
+	if (ret)
+		return ret;
+	/* Keep the value of buf[1] unchanged.*/
+	buf[0] = SPINOR_REG_CR2_SPI;
+
+	ret = spi_nor_macronix_write_cr2(nor, buf, 2);
+	if (ret)
+		return ret;
+
+	ret = spi_nor_read_id(nor, 0, 0, buf, nor->reg_proto);
+	if (ret)
+		return ret;
+
+	if (memcmp(buf, nor->info->id, nor->info->id_len)) {
+		dev_dbg(nor->dev, "Failed to disable 8D-8D-8D mode.\n");
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int spi_nor_macronix_octal_dtr_enable(struct spi_nor *nor, bool enable)
+{
+	return enable ? spi_nor_macronix_octal_dtr_en(nor) :
+			spi_nor_macronix_octal_dtr_dis(nor);
+}
+
+static void mx66lm1g45g_late_init(struct spi_nor *nor)
+{
+	nor->params->octal_dtr_enable = spi_nor_macronix_octal_dtr_enable;
+
+	/* Set the Fast Read settings. */
+	nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR;
+	spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_8_8_8_DTR],
+				  0, 20, SPINOR_OP_MX_DTR_RD,
+				  SNOR_PROTO_8_8_8_DTR);
+
+	nor->cmd_ext_type = SPI_NOR_EXT_INVERT;
+	nor->params->rdsr_dummy = 4;
+	nor->params->rdsr_addr_nbytes = 4;
+}
+
+static struct spi_nor_fixups mx66lm1g45g_fixups = {
+	.late_init = mx66lm1g45g_late_init,
+};
+
 static int
 mx25l25635_post_bfpt_fixups(struct spi_nor *nor,
 			    const struct sfdp_parameter_header *bfpt_header,
@@ -100,6 +224,13 @@ static const struct flash_info macronix_parts[] = {
 	{ "mx66u2g45g",	 INFO(0xc2253c, 0, 64 * 1024, 4096)
 		NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
 		FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
+	{ "mx66lm1g45g", INFO(0xc2853b, 0, 64 * 1024, 2048)
+		NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SECT_4K |
+			      SPI_NOR_OCTAL_DTR_READ | SPI_NOR_OCTAL_DTR_PP)
+		FIXUP_FLAGS(SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE |
+			    SPI_NOR_SOFT_RESET)
+		.fixups = &mx66lm1g45g_fixups,
+	},
 };
 
 static void macronix_default_init(struct spi_nor *nor)
-- 
2.25.1


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

* Re: [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name
  2022-02-09 13:36 ` [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name Tudor Ambarus
@ 2022-03-21 11:53   ` Pratyush Yadav
  2022-03-21 11:55     ` Pratyush Yadav
  0 siblings, 1 reply; 10+ messages in thread
From: Pratyush Yadav @ 2022-03-21 11:53 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: michael, miquel.raynal, richard, vigneshr, linux-mtd,
	linux-kernel, nicolas.ferre, zhengxunli, jaimeliao

On 09/02/22 03:36PM, Tudor Ambarus wrote:
> The method is matching a flash_info entry by searching by name. Rename
> the method for better clarity.
> 
> Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>

Reviewed-by: Pratyush Yadav <p.yadav@ti.com>

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

* Re: [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name
  2022-03-21 11:53   ` Pratyush Yadav
@ 2022-03-21 11:55     ` Pratyush Yadav
  0 siblings, 0 replies; 10+ messages in thread
From: Pratyush Yadav @ 2022-03-21 11:55 UTC (permalink / raw)
  To: Tudor Ambarus
  Cc: michael, miquel.raynal, richard, vigneshr, linux-mtd,
	linux-kernel, nicolas.ferre, zhengxunli, jaimeliao

On 21/03/22 05:23PM, Pratyush Yadav wrote:
> On 09/02/22 03:36PM, Tudor Ambarus wrote:
> > The method is matching a flash_info entry by searching by name. Rename
> > the method for better clarity.
> > 
> > Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
> 
> Reviewed-by: Pratyush Yadav <p.yadav@ti.com>

Looks like you have sent another series with these patches. Let me 
review that instead.

-- 
Regards,
Pratyush Yadav
Texas Instruments Inc.

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

end of thread, other threads:[~2022-03-21 11:56 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-09 13:36 [PATCH v6 0/7] mtd: spi-nor: Prepare core and add support for mx66lm1g45g Tudor Ambarus
2022-02-09 13:36 ` [PATCH v6 1/7] mtd: spi-nor: Rename method, s/spi_nor_match_id/spi_nor_match_name Tudor Ambarus
2022-03-21 11:53   ` Pratyush Yadav
2022-03-21 11:55     ` Pratyush Yadav
2022-02-09 13:36 ` [PATCH v6 2/7] mtd: spi-nor: Introduce spi_nor_match_id() Tudor Ambarus
2022-02-09 13:36 ` [PATCH v6 3/7] mtd: spi-nor: core: Use auto-detection only once Tudor Ambarus
2022-02-09 13:36 ` [PATCH v6 4/7] mtd: spi-nor: core: Introduce method for RDID op Tudor Ambarus
2022-02-09 13:36 ` [PATCH v6 5/7] mtd: spi-nor: manufacturers: Use spi_nor_read_id() core method Tudor Ambarus
2022-02-09 13:36 ` [PATCH v6 6/7] mtd: spi-nor: core: Introduce SPI_NOR_SOFT_RESET flash_info fixup_flag Tudor Ambarus
2022-02-09 13:36 ` [PATCH v6 7/7] mtd: spi-nor: macronix: Add support for mx66lm1g45g Tudor Ambarus

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).