From 7b08e6f926d618b3636ad946fe14a1c43d6aed31 Mon Sep 17 00:00:00 2001 From: Nathan Barrett-Morrison Date: Wed, 23 Nov 2022 16:13:35 -0500 Subject: [PATCH] mtd: spi-nor: issi: Add in support for IS25LX256 chip, operating in Octal STR mode Adds the is25lx256 entry to the nor_parts table along with the additional STR enablement fixups and logic Signed-off-by: Nathan Barrett-Morrison --- drivers/mtd/spi-nor/issi.c | 101 +++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c index 89a66a19d754f2..89f3cdd5107509 100644 --- a/drivers/mtd/spi-nor/issi.c +++ b/drivers/mtd/spi-nor/issi.c @@ -8,6 +8,15 @@ #include "core.h" +#define SPINOR_OP_STR_RD 0x8B /* Fast Read opcode in DTR mode */ +#define SPINOR_OP_STR_PP 0x82 /* Octal Input Fast Program */ +#define SPINOR_OP_RD_ANY_REG 0x85 /* Read volatile register */ +#define SPINOR_OP_WR_ANY_REG 0x81 /* Write volatile register */ +#define SPINOR_REG_CFR0V 0x00 /* For setting octal DTR mode */ +#define SPINOR_REG_CFR1V 0x01 /* For setting dummy cycles */ +#define SPINOR_OCT_STR 0xc7 /* Enable Octal DTR. */ +#define SPINOR_EXSPI 0xff /* Enable Extended SPI (default) */ + static int is25lp256_post_bfpt_fixups(struct spi_nor *nor, const struct sfdp_parameter_header *bfpt_header, @@ -29,6 +38,94 @@ static const struct spi_nor_fixups is25lp256_fixups = { .post_bfpt = is25lp256_post_bfpt_fixups, }; +static int spi_nor_issi_octal_str_enable(struct spi_nor *nor, bool enable) +{ + struct spi_mem_op op; + u8 *buf = nor->bouncebuf; + int ret; + + ret = spi_nor_write_enable(nor); + if (ret) + return ret; + + if (enable) + *buf = SPINOR_OCT_STR; + else + *buf = SPINOR_EXSPI; + + op = (struct spi_mem_op) + SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), + SPI_MEM_OP_ADDR(enable ? 3 : 4, + SPINOR_REG_CFR0V, 1), + SPI_MEM_OP_NO_DUMMY, + SPI_MEM_OP_DATA_OUT(1, buf, 1)); + + if (!enable) + spi_nor_spimem_setup_op(nor, &op, SNOR_PROTO_1_1_8); + else + spi_nor_spimem_setup_op(nor, &op, SNOR_PROTO_1_1_1); + + + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) + 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_NO_DUMMY, + 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_1_1_8); + else + spi_nor_spimem_setup_op(nor, &op, SNOR_PROTO_1_1_1); + + + ret = spi_mem_exec_op(nor->spimem, &op); + if (ret) + return ret; + + if (memcmp(buf, nor->info->id, nor->info->id_len)) + return -EINVAL; + + return 0; +} + +static void is25lx256_default_init(struct spi_nor *nor) +{ + nor->params->octal_str_enable = spi_nor_issi_octal_str_enable; +} + +static void is25lx256_post_sfdp_fixup(struct spi_nor *nor) +{ + /* Fixup read command to 8 dummy cycles, 1S-1S-8S */ + nor->params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8; + spi_nor_set_read_settings(&nor->params->reads[SNOR_CMD_READ_8_8_8], + 0, 8, SPINOR_OP_STR_RD, + SNOR_PROTO_1_1_8); + + /* Fixup page program command to 1S-1S-8S */ + nor->params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8; + spi_nor_set_pp_settings(&nor->params->page_programs[SNOR_CMD_PP_8_8_8], + SPINOR_OP_STR_PP, SNOR_PROTO_1_1_8); + + /* + * The BFPT quad enable field is set to a reserved value so the quad + * enable function is ignored by spi_nor_parse_bfpt(). Make sure we + * disable it. + */ + nor->params->quad_enable = NULL; +} + +static struct spi_nor_fixups is25lx256_fixups = { + .default_init = is25lx256_default_init, + .post_sfdp = is25lx256_post_sfdp_fixup, +}; + static void pm25lv_nor_late_init(struct spi_nor *nor) { struct spi_nor_erase_map *map = &nor->params->erase_map; @@ -74,6 +171,10 @@ static const struct flash_info issi_nor_parts[] = { NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) FIXUP_FLAGS(SPI_NOR_4B_OPCODES) .fixups = &is25lp256_fixups }, + { "is25lx256", INFO(0x9d5a19, 0, 128 * 1024, 256) + NO_SFDP_FLAGS(SECT_4K | SPI_NOR_OCTAL_STR_PP | SPI_NOR_OCTAL_STR_READ) + FIXUP_FLAGS(SPI_NOR_4B_OPCODES | SPI_NOR_IO_MODE_EN_VOLATILE) + .fixups = &is25lx256_fixups }, /* PMC */ { "pm25lv512", INFO(0, 0, 32 * 1024, 2)