diff mbox series

[4/4] mtd: spi-nor-core: Rework s25hx_t_post_bfpt_fixup() for flash's internal address mode

Message ID 9a961f8ee872bd4fc8ffb8dcc3494ea4f0c95a62.1662011338.git.Takahiro.Kuwano@infineon.com
State Accepted
Delegated to: Jagannadha Sutradharudu Teki
Headers show
Series mtd: spi-nor-core: Track flash's internal address mode in s25hx-t | expand

Commit Message

Takahiro Kuwano Sept. 1, 2022, 6:05 a.m. UTC
From: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>

The flash's internal address mode is tracked by nor->add_mode_nbytes and
it is set to 3 in BFPT parse. SEMPER multi-die package parts (>1Gb) are
3- or 4-byte address mode by default, depending on model number. We need
to make sure that 4-byte address mode is used for multi-die package parts.

For single-die package parts (<=1Gb), registers can be accessed by 3-byte
address. Read, program, and erase use the 4B opcodes that always take
4-byte address regardless of flash's internal address mode.

Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano@infineon.com>
---
 drivers/mtd/spi/spi-nor-core.c | 23 +++++++++++++++++++----
 1 file changed, 19 insertions(+), 4 deletions(-)
diff mbox series

Patch

diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index 9f08970188..0cbc647710 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -161,6 +161,7 @@  struct sfdp_header {
 #define BFPT_DWORD15_QER_SR2_BIT1		(0x5UL << 20) /* Spansion */
 
 #define BFPT_DWORD16_SOFT_RST			BIT(12)
+#define BFPT_DWORD16_EX4B_PWRCYC		BIT(21)
 
 #define BFPT_DWORD18_CMD_EXT_MASK		GENMASK(30, 29)
 #define BFPT_DWORD18_CMD_EXT_REP		(0x0UL << 29) /* Repeat */
@@ -3253,10 +3254,24 @@  static int s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
 	nor->erase_opcode = SPINOR_OP_SE_4B;
 	nor->mtd.erasesize = nor->info->sector_size;
 
-	ret = set_4byte(nor, nor->info, 1);
-	if (ret)
-		return ret;
-	nor->addr_width = 4;
+	/*
+	 * The default address mode in multi-die package parts (>1Gb) may be
+	 * 3- or 4-byte, depending on model number. BootROM code in some SoCs
+	 * use 3-byte mode for backward compatibility and should switch to
+	 * 4-byte mode after BootROM phase. Since registers in the 2nd die are
+	 * mapped within 32-bit address space, we need to make sure the flash is
+	 * in 4-byte address mode. The default address mode can be distinguished
+	 * by BFPT 16th DWORD. Power cycle exits 4-byte address mode if default
+	 * is 3-byte address mode.
+	 */
+	if (params->size > SZ_128M) {
+		if (bfpt->dwords[BFPT_DWORD(16)] & BFPT_DWORD16_EX4B_PWRCYC) {
+			ret = set_4byte(nor, nor->info, 1);
+			if (ret)
+				return ret;
+		}
+		nor->addr_mode_nbytes = 4;
+	}
 
 	/*
 	 * The page_size is set to 512B from BFPT, but it actually depends on