[PATCH 2/3] mtd: spi-nor-core: macronix: Add support for mx66lm1g45g

Tudor Ambarus tudor.ambarus at microchip.com
Wed Nov 3 17:24:53 CET 2021


mx66lm1g45g supports just 1-1-1, 8-8-8 and 8d-8d-8d modes.
Tested in 1-1-1 and 8d-8d-8d modes using microchip's Octal SPI IP.

Signed-off-by: Tudor Ambarus <tudor.ambarus at microchip.com>
---
 drivers/mtd/spi/Kconfig        |  8 ++++
 drivers/mtd/spi/spi-nor-core.c | 74 ++++++++++++++++++++++++++++++++++
 drivers/mtd/spi/spi-nor-ids.c  |  6 +++
 include/linux/mtd/spi-nor.h    |  8 ++++
 4 files changed, 96 insertions(+)

diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 408a53f861..2d2b71c52d 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -160,6 +160,14 @@ config SPI_FLASH_MACRONIX
 	help
 	  Add support for various Macronix SPI flash chips (MX25Lxxx)
 
+config SPI_FLASH_MX66LM1G45G
+	bool "Macronix MX66LM1G45G chip support"
+	depends on SPI_FLASH_MACRONIX
+	help
+	  Add support for the Macronix mx66lm1g45g chip. This is a separate
+	  config because the fixup hooks for this flash add extra size overhead.
+	  Boards that don't use the flash can disable this to save space.
+
 config SPI_FLASH_SPANSION
 	bool "Spansion SPI flash support"
 	help
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index ce1ecae899..df66a73495 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -3526,6 +3526,75 @@ static struct spi_nor_fixups mt35xu512aba_fixups = {
 };
 #endif /* CONFIG_SPI_FLASH_MT35XU */
 
+#ifdef CONFIG_SPI_FLASH_MX66LM1G45G
+static int spi_nor_macronix_octal_dtr_enable(struct spi_nor *nor)
+{
+	struct spi_mem_op op;
+	u8 buf;
+	int ret;
+
+	/* Use 20 dummy cycles for memory array reads. */
+	buf = SPINOR_REG_CR2_DUMMY_20;
+	op = (struct spi_mem_op)
+		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRITE_CR2, 1),
+			   SPI_MEM_OP_ADDR(4, SPINOR_REG_CR2_DUMMY_ADDR,
+					   1),
+			   SPI_MEM_OP_NO_DUMMY,
+			   SPI_MEM_OP_DATA_OUT(1, &buf, 1));
+
+	ret = write_enable(nor);
+	if (ret)
+		return ret;
+
+	ret = spi_mem_exec_op(nor->spi, &op);
+	if (ret)
+		return ret;
+
+	ret = spi_nor_wait_till_ready(nor);
+	if (ret)
+		return ret;
+
+	buf = SPINOR_REG_CR2_DTR_OPI_ENABLE;
+	op = (struct spi_mem_op)
+		SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WRITE_CR2, 1),
+			   SPI_MEM_OP_ADDR(4, SPINOR_REG_CR2_MODE_ADDR, 1),
+			   SPI_MEM_OP_NO_DUMMY,
+			   SPI_MEM_OP_DATA_OUT(1, &buf, 1));
+
+	ret = write_enable(nor);
+	if (ret)
+		return ret;
+
+	return spi_mem_exec_op(nor->spi, &op);
+}
+
+static void mx66lm1g45g_default_init(struct spi_nor *nor)
+{
+	nor->octal_dtr_enable = spi_nor_macronix_octal_dtr_enable;
+}
+
+static void mx66lm1g45g_post_sfdp(struct spi_nor *nor,
+				  struct spi_nor_flash_parameter *params)
+{
+	/* Set the Fast Read settings. */
+	params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR;
+	spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_8_8_8_DTR],
+				  0, 20, SPINOR_OP_MX_DTR_RD,
+				  SNOR_PROTO_8_8_8_DTR);
+
+	params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
+
+	nor->cmd_ext_type = SPI_NOR_EXT_INVERT;
+	params->rdsr_dummy = 4;
+	params->rdsr_addr_nbytes = 4;
+}
+
+static struct spi_nor_fixups mx66lm1g45g_fixups = {
+	.default_init = mx66lm1g45g_default_init,
+	.post_sfdp = mx66lm1g45g_post_sfdp,
+};
+#endif /* CONFIG_SPI_FLASH_MX66LM1G45G */
+
 /** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed
  * @nor:                 pointer to a 'struct spi_nor'
  *
@@ -3696,6 +3765,11 @@ void spi_nor_set_fixups(struct spi_nor *nor)
 	if (!strcmp(nor->info->name, "mt35xu512aba"))
 		nor->fixups = &mt35xu512aba_fixups;
 #endif
+
+#ifdef CONFIG_SPI_FLASH_MX66LM1G45G
+	if (!strcmp(nor->info->name, "mx66lm1g45g"))
+		nor->fixups = &mx66lm1g45g_fixups;
+#endif
 }
 
 int spi_nor_scan(struct spi_nor *nor)
diff --git a/drivers/mtd/spi/spi-nor-ids.c b/drivers/mtd/spi/spi-nor-ids.c
index 3ae7bb1ed7..d5bc106e68 100644
--- a/drivers/mtd/spi/spi-nor-ids.c
+++ b/drivers/mtd/spi/spi-nor-ids.c
@@ -179,6 +179,12 @@ const struct flash_info spi_nor_ids[] = {
 	{ INFO("mx25l1633e", 0xc22415, 0, 64 * 1024,   32, SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES | SECT_4K) },
 	{ INFO("mx25r6435f", 0xc22817, 0, 64 * 1024,   128,  SECT_4K) },
 	{ INFO("mx66uw2g345g", 0xc2943c, 0, 64 * 1024, 4096, SECT_4K | SPI_NOR_OCTAL_READ | SPI_NOR_4B_OPCODES) },
+#ifdef CONFIG_SPI_FLASH_MX66LM1G45G
+	{ INFO("mx66lm1g45g", 0xc2853b, 0, 64 * 1024, 2048,
+	       SPI_NOR_SKIP_SFDP | SPI_NOR_SOFT_RESET |
+	       SECT_4K | SPI_NOR_OCTAL_DTR_READ | SPI_NOR_4B_OPCODES)
+	},
+#endif
 #endif
 
 #ifdef CONFIG_SPI_FLASH_STMICRO		/* STMICRO */
diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
index 4ceeae623d..c8b8a242ba 100644
--- a/include/linux/mtd/spi-nor.h
+++ b/include/linux/mtd/spi-nor.h
@@ -119,6 +119,14 @@
 /* Used for Macronix and Winbond flashes. */
 #define SPINOR_OP_EN4B		0xb7	/* Enter 4-byte mode */
 #define SPINOR_OP_EX4B		0xe9	/* Exit 4-byte mode */
+#define SPINOR_OP_READ_CR2		0x71
+#define SPINOR_OP_WRITE_CR2		0x72
+#define SPINOR_OP_MX_DTR_RD		0xee
+#define SPINOR_REG_CR2_MODE_ADDR	0
+#define SPINOR_REG_CR2_DTR_OPI_ENABLE	BIT(1)
+#define SPINOR_REG_CR2_SPI		0
+#define SPINOR_REG_CR2_DUMMY_ADDR	0x300
+#define SPINOR_REG_CR2_DUMMY_20		0
 
 /* Used for Spansion flashes only. */
 #define SPINOR_OP_BRWR		0x17	/* Bank register write */
-- 
2.25.1



More information about the U-Boot mailing list