All of lore.kernel.org
 help / color / mirror / Atom feed
From: tkuw584924@gmail.com
To: linux-mtd@lists.infradead.org
Cc: tudor.ambarus@microchip.com, miquel.raynal@bootlin.com,
	richard@nod.at, vigneshr@ti.com, p.yadav@ti.com,
	michael@walle.cc, tkuw584924@gmail.com,
	Bacem.Daassi@infineon.com,
	Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Subject: [PATCH v15 5/8] mtd: spi-nor: core: Couple the number of address bytes with the address mode
Date: Tue, 10 May 2022 07:10:06 +0900	[thread overview]
Message-ID: <e79c68ce2a82ecfa301962104c877401417a5a62.1652063152.git.Takahiro.Kuwano@infineon.com> (raw)
In-Reply-To: <cover.1652063152.git.Takahiro.Kuwano@infineon.com>

From: Tudor Ambarus <tudor.ambarus@microchip.com>

Some of Infineon chips support volatile version of configuration registers
and it is recommended to update volatile registers in the field application
due to a risk of the non-volatile registers corruption by power interrupt.
Such a volatile configuration register is used to enable the Quad mode.
The register write sequence requires the number of bytes of address in
order to be programmed. As it was before, the nor->addr_nbytes was set to 4
before calling the volatile Quad enable method. This was incorrect because
the Write Any Register command does not have a 4B opcode equivalent and the
address mode was still at default (3-byte mode) and not changed to 4 by
entering in the 4 Byte Address Mode, so the operation failed.

Move the setting of the number of bytes of address after the Quad Enable
method to allow reads or writes to registers that require the number of
address bytes to work with the default address mode. The number of address
bytes and the address mode are tightly coupled, this is a natural change.

Other (standard) Quad Enable methods are not affected, as they don't
require the number of address bytes, so no functionality changes expected.

Reported-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Tested-By: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
---
 drivers/mtd/spi-nor/core.c | 134 +++++++++++++++++++------------------
 1 file changed, 70 insertions(+), 64 deletions(-)

diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
index dd71deba9f11..1c14a95a23fd 100644
--- a/drivers/mtd/spi-nor/core.c
+++ b/drivers/mtd/spi-nor/core.c
@@ -2270,49 +2270,6 @@ static int spi_nor_default_setup(struct spi_nor *nor,
 	return 0;
 }
 
-static int spi_nor_set_addr_nbytes(struct spi_nor *nor)
-{
-	if (nor->params->addr_nbytes) {
-		nor->addr_nbytes = nor->params->addr_nbytes;
-	} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) {
-		/*
-		 * In 8D-8D-8D mode, one byte takes half a cycle to transfer. So
-		 * in this protocol an odd address width cannot be used because
-		 * then the address phase would only span a cycle and a half.
-		 * Half a cycle would be left over. We would then have to start
-		 * the dummy phase in the middle of a cycle and so too the data
-		 * phase, and we will end the transaction with half a cycle left
-		 * over.
-		 *
-		 * Force all 8D-8D-8D flashes to use an address width of 4 to
-		 * avoid this situation.
-		 */
-		nor->addr_nbytes = 4;
-	} else if (nor->info->addr_nbytes) {
-		nor->addr_nbytes = nor->info->addr_nbytes;
-	} else {
-		nor->addr_nbytes = 3;
-	}
-
-	if (nor->addr_nbytes == 3 && nor->params->size > 0x1000000) {
-		/* enable 4-byte addressing if the device exceeds 16MiB */
-		nor->addr_nbytes = 4;
-	}
-
-	if (nor->addr_nbytes > SPI_NOR_MAX_ADDR_NBYTES) {
-		dev_dbg(nor->dev, "address width is too large: %u\n",
-			nor->addr_nbytes);
-		return -EINVAL;
-	}
-
-	/* Set 4byte opcodes when possible. */
-	if (nor->addr_nbytes == 4 && nor->flags & SNOR_F_4B_OPCODES &&
-	    !(nor->flags & SNOR_F_HAS_4BAIT))
-		spi_nor_set_4byte_opcodes(nor);
-
-	return 0;
-}
-
 static int spi_nor_setup(struct spi_nor *nor,
 			 const struct spi_nor_hwcaps *hwcaps)
 {
@@ -2322,10 +2279,7 @@ static int spi_nor_setup(struct spi_nor *nor,
 		ret = nor->params->setup(nor, hwcaps);
 	else
 		ret = spi_nor_default_setup(nor, hwcaps);
-	if (ret)
-		return ret;
-
-	return spi_nor_set_addr_nbytes(nor);
+	return ret;
 }
 
 /**
@@ -2707,6 +2661,74 @@ static int spi_nor_quad_enable(struct spi_nor *nor)
 	return nor->params->quad_enable(nor);
 }
 
+static int spi_nor_set_addr_nbytes(struct spi_nor *nor)
+{
+	if (nor->params->addr_nbytes) {
+		nor->addr_nbytes = nor->params->addr_nbytes;
+	} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) {
+		/*
+		 * In 8D-8D-8D mode, one byte takes half a cycle to transfer. So
+		 * in this protocol an odd address width cannot be used because
+		 * then the address phase would only span a cycle and a half.
+		 * Half a cycle would be left over. We would then have to start
+		 * the dummy phase in the middle of a cycle and so too the data
+		 * phase, and we will end the transaction with half a cycle left
+		 * over.
+		 *
+		 * Force all 8D-8D-8D flashes to use an address width of 4 to
+		 * avoid this situation.
+		 */
+		nor->addr_nbytes = 4;
+	} else if (nor->info->addr_nbytes) {
+		nor->addr_nbytes = nor->info->addr_nbytes;
+	} else {
+		nor->addr_nbytes = 3;
+	}
+
+	if (nor->addr_nbytes == 3 && nor->params->size > 0x1000000) {
+		/* enable 4-byte addressing if the device exceeds 16MiB */
+		nor->addr_nbytes = 4;
+	}
+
+	if (nor->addr_nbytes > SPI_NOR_MAX_ADDR_NBYTES) {
+		dev_dbg(nor->dev, "address width is too large: %u\n",
+			nor->addr_nbytes);
+		return -EINVAL;
+	}
+
+	/* Set 4byte opcodes when possible. */
+	if (nor->addr_nbytes == 4 && nor->flags & SNOR_F_4B_OPCODES &&
+	    !(nor->flags & SNOR_F_HAS_4BAIT))
+		spi_nor_set_4byte_opcodes(nor);
+
+	return 0;
+}
+
+static int spi_nor_set_addr_mode(struct spi_nor *nor)
+{
+	int ret;
+
+	ret = spi_nor_set_addr_nbytes(nor);
+	if (ret)
+		return ret;
+
+	if (nor->addr_nbytes == 4 && nor->read_proto != SNOR_PROTO_8_8_8_DTR &&
+	    !(nor->flags & SNOR_F_4B_OPCODES)) {
+		/*
+		 * If the RESET# pin isn't hooked up properly, or the system
+		 * otherwise doesn't perform a reset command in the boot
+		 * sequence, it's impossible to 100% protect against unexpected
+		 * reboots (e.g., crashes). Warn the user (or hopefully, system
+		 * designer) that this is bad.
+		 */
+		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
+			  "enabling reset hack; may not recover from unexpected reboots\n");
+		nor->params->set_4byte_addr_mode(nor, true);
+	}
+
+	return 0;
+}
+
 static int spi_nor_init(struct spi_nor *nor)
 {
 	int err;
@@ -2738,22 +2760,7 @@ static int spi_nor_init(struct spi_nor *nor)
 	     nor->flags & SNOR_F_SWP_IS_VOLATILE))
 		spi_nor_try_unlock_all(nor);
 
-	if (nor->addr_nbytes == 4 &&
-	    nor->read_proto != SNOR_PROTO_8_8_8_DTR &&
-	    !(nor->flags & SNOR_F_4B_OPCODES)) {
-		/*
-		 * If the RESET# pin isn't hooked up properly, or the system
-		 * otherwise doesn't perform a reset command in the boot
-		 * sequence, it's impossible to 100% protect against unexpected
-		 * reboots (e.g., crashes). Warn the user (or hopefully, system
-		 * designer) that this is bad.
-		 */
-		WARN_ONCE(nor->flags & SNOR_F_BROKEN_RESET,
-			  "enabling reset hack; may not recover from unexpected reboots\n");
-		nor->params->set_4byte_addr_mode(nor, true);
-	}
-
-	return 0;
+	return spi_nor_set_addr_mode(nor);
 }
 
 /**
@@ -3014,7 +3021,6 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
 	 * - select op codes for (Fast) Read, Page Program and Sector Erase.
 	 * - set the number of dummy cycles (mode cycles + wait states).
 	 * - set the SPI protocols for register and memory accesses.
-	 * - set the address width.
 	 */
 	ret = spi_nor_setup(nor, hwcaps);
 	if (ret)
-- 
2.25.1


______________________________________________________
Linux MTD discussion mailing list
http://lists.infradead.org/mailman/listinfo/linux-mtd/

  parent reply	other threads:[~2022-05-09 22:11 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-09 22:10 [PATCH v15 0/8] mtd: spi-nor: Add support for Infineon s25hl-t/s25hs-t tkuw584924
2022-05-09 22:10 ` [PATCH v15 1/8] mtd: spi-nor: s/addr_width/addr_nbytes tkuw584924
2022-05-12 21:01   ` Michael Walle
2022-05-31 11:13   ` Pratyush Yadav
2022-05-09 22:10 ` [PATCH v15 2/8] mtd: spi-nor: core: Shrink the storage size of the flash_info's addr_nbytes tkuw584924
2022-05-12 21:22   ` Michael Walle
2022-05-31 11:14   ` Pratyush Yadav
2022-05-09 22:10 ` [PATCH v15 3/8] mtd: spi-nor: sfdp: Clarify that nor->read_{opcode, dummy} are uninitialized tkuw584924
2022-05-12 21:33   ` Michael Walle
2022-05-12 21:38     ` Michael Walle
2022-05-31 11:18   ` Pratyush Yadav
2022-05-09 22:10 ` [PATCH v15 4/8] mtd: spi-nor: Do not change nor->addr_nbytes at SFDP parsing time tkuw584924
2022-05-12 21:45   ` Michael Walle
2022-05-31 11:30   ` Pratyush Yadav
2022-07-21 14:32     ` Tudor.Ambarus
2022-07-21 15:02     ` Tudor.Ambarus
2022-05-09 22:10 ` tkuw584924 [this message]
2022-05-12 22:07   ` [PATCH v15 5/8] mtd: spi-nor: core: Couple the number of address bytes with the address mode Michael Walle
2022-05-09 22:10 ` [PATCH v15 6/8] mtd: spi-nor: Retain nor->addr_width at 4BAIT parse tkuw584924
2022-05-12 22:14   ` Michael Walle
2022-05-13  1:26     ` Takahiro Kuwano
2022-05-13  9:40       ` Michael Walle
2022-05-14  3:51         ` Takahiro Kuwano
2022-05-18  6:04           ` Takahiro Kuwano
2022-05-18  8:35             ` Michael Walle
2022-05-18  9:12               ` Takahiro Kuwano
2022-05-23  7:49           ` Michael Walle
2022-05-23  9:56             ` Takahiro Kuwano
2022-06-03  9:33               ` Takahiro Kuwano
2022-07-21 16:06             ` Tudor.Ambarus
2022-07-22  4:00               ` Takahiro Kuwano
2022-07-22  4:20                 ` Tudor.Ambarus
2022-07-22  4:31                   ` Vanessa Page
2022-07-22  4:46                   ` Takahiro Kuwano
2022-07-22  5:06                     ` Tudor.Ambarus
2022-07-22  5:11                       ` Takahiro Kuwano
2022-07-22  6:08                         ` Tudor.Ambarus
2022-07-22  7:38                           ` Tudor.Ambarus
2022-07-22  7:45                             ` Tudor.Ambarus
2022-06-08 11:39           ` Tudor.Ambarus
2022-05-09 22:10 ` [PATCH v15 7/8] mtd: spi-nor: spansion: Add local function to discover page size tkuw584924
2022-05-09 22:10 ` [PATCH v15 8/8] mtd: spi-nor: spansion: Add s25hl-t/s25hs-t IDs and fixups tkuw584924

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=e79c68ce2a82ecfa301962104c877401417a5a62.1652063152.git.Takahiro.Kuwano@infineon.com \
    --to=tkuw584924@gmail.com \
    --cc=Bacem.Daassi@infineon.com \
    --cc=Takahiro.Kuwano@infineon.com \
    --cc=linux-mtd@lists.infradead.org \
    --cc=michael@walle.cc \
    --cc=miquel.raynal@bootlin.com \
    --cc=p.yadav@ti.com \
    --cc=richard@nod.at \
    --cc=tudor.ambarus@microchip.com \
    --cc=vigneshr@ti.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.