Make a generic post_bfpt fixup handler which uses part specific fixup's based on device id, as done here for is25lp256 and is25wp256 devices. During SFDP parsing it is seen that the IS25WP256d device is missing 4BAIT (4-Byte address instruction table), due to which it's page program capacity doesn't get correctly populated and the device gets configured with 4-byte Address Serial Input Page Program i.e. SNOR_PROTO_1_1_1 even though it can work with SNOR_PROTO_1_1_4. Here using the post bfpt fixup hooks we update the page program settings to 4-byte QUAD Input Page program operations. The patch is tested on HiFive Unleashed A00 board and it benefits few seconds of average write time for entire flash write. QUAD Input Page Program operations: > time mtd_debug write /dev/mtd0 0 33554432 rd32M Copied 33554432 bytes from rd32M to address 0x00000000 in flash real 0m 35.23s user 0m 0.00s sys 0m 23.97s Serial Input Page Program operations: > time mtd_debug write /dev/mtd0 0 33554432 rd32M Copied 33554432 bytes from rd32M to address 0x00000000 in flash real 0m 39.25s user 0m 0.00s sys 0m 27.93s Signed-off-by: Sagar Shrikant Kadam <sagar.kadam@xxxxxxxxxx> --- drivers/mtd/spi-nor/issi.c | 72 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/spi-nor/issi.c b/drivers/mtd/spi-nor/issi.c index ffcb60e..efa0fe7 100644 --- a/drivers/mtd/spi-nor/issi.c +++ b/drivers/mtd/spi-nor/issi.c @@ -8,26 +8,74 @@ #include "core.h" -static int -is25lp256_post_bfpt_fixups(struct spi_nor *nor, - const struct sfdp_parameter_header *bfpt_header, - const struct sfdp_bfpt *bfpt, - struct spi_nor_flash_parameter *params) +static int issi_fix_addr_width(struct spi_nor *nor, + const struct sfdp_bfpt *bfpt) { /* - * IS25LP256 supports 4B opcodes, but the BFPT advertises a + * If device supports 4B opcodes, but the BFPT advertises a * BFPT_DWORD1_ADDRESS_BYTES_3_ONLY address width. * Overwrite the address width advertised by the BFPT. */ - if ((bfpt->dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) == - BFPT_DWORD1_ADDRESS_BYTES_3_ONLY) + if ((bfpt->dwords[BFPT_DWORD(1)] & BFPT_DWORD1_ADDRESS_BYTES_MASK) + == BFPT_DWORD1_ADDRESS_BYTES_3_ONLY) nor->addr_width = 4; return 0; } -static struct spi_nor_fixups is25lp256_fixups = { - .post_bfpt = is25lp256_post_bfpt_fixups, +static int issi_update_proto(struct spi_nor *nor, + struct spi_nor_flash_parameter *params) +{ + /* + * For a device whose 4-Byte address instruction table doesn't + * get populated and the device get's configured with 4-byte + * Address Serial Input Page Program i.e. SNOR_PROTO_1_1_1 even + * though it supports SNOR_PROTO_1_1_4, so priorotize QUAD write + * over SINGLE write if device id table holds SPI_NOR_QUAD_READ. + */ + if (nor->info->flags & SPI_NOR_QUAD_READ) { + params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4; + spi_nor_set_pp_settings + (¶ms->page_programs[SNOR_CMD_PP_1_1_4], + SPINOR_OP_PP_1_1_4, + SNOR_PROTO_1_1_4); + } + + return 0; +} + +static int +issi_post_bfpt_fixups(struct spi_nor *nor, + const struct sfdp_parameter_header *bfpt_header, + const struct sfdp_bfpt *bfpt, + struct spi_nor_flash_parameter *params) +{ + long deviceid; + + deviceid = (nor->info->id[1] << 8 | nor->info->id[2]); + + /* As this is for same MFR i.e ISSI, just check the device ID's */ + switch (deviceid) { + case 0x6019: + /* is25lp256 */ + issi_fix_addr_width(nor, bfpt); + break; + + case 0x7019: + /* is25wp256 */ + issi_fix_addr_width(nor, bfpt); + issi_update_proto(nor, params); + break; + + default: + break; + } + + return 0; +} + +static struct spi_nor_fixups is25_fixups = { + .post_bfpt = issi_post_bfpt_fixups, }; static const struct flash_info issi_parts[] = { @@ -48,7 +96,7 @@ static const struct flash_info issi_parts[] = { { "is25lp256", INFO(0x9d6019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) - .fixups = &is25lp256_fixups }, + .fixups = &is25_fixups }, { "is25wp032", INFO(0x9d7016, 0, 64 * 1024, 64, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "is25wp064", INFO(0x9d7017, 0, 64 * 1024, 128, @@ -58,7 +106,7 @@ static const struct flash_info issi_parts[] = { { "is25wp256", INFO(0x9d7019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SPI_NOR_4B_OPCODES) - .fixups = &is25lp256_fixups }, + .fixups = &is25_fixups }, /* PMC */ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, -- 2.7.4 ______________________________________________________ Linux MTD discussion mailing list http://lists.infradead.org/mailman/listinfo/linux-mtd/