
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@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(¶ms->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 */