From 95d0d54019ec291bf5430090dccb6dd66ea87de7 Mon Sep 17 00:00:00 2001 From: Han Xu Date: Mon, 5 Jun 2017 16:19:39 -0500 Subject: [PATCH] MLK-15052-3: mtd: spi-nor: enable octal read mode in spi framework Enhanced spi-nor framework to support octal read mode Signed-off-by: Han Xu Acked-by: Frank Li --- drivers/mtd/spi-nor/spi-nor.c | 19 +++++++++++++++++-- include/linux/mtd/spi-nor.h | 9 ++++++--- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index 0b6134f48d66..76087e80ceb0 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -77,6 +77,7 @@ struct flash_info { * SPI_NOR_HAS_LOCK. */ #define SPI_NOR_DDR_QUAD_READ BIT(10) /* Flash supports DDR Quad Read */ +#define SPI_NOR_DDR_OCTAL_READ BIT(11) /* Flash supports DDR Octal Read */ }; #define JEDEC_MFR(info) ((info)->id[0]) @@ -149,6 +150,7 @@ static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor) { switch (nor->flash_read) { case SPI_NOR_DDR_QUAD: + case SPI_NOR_DDR_OCTAL: { struct device_node *np = spi_nor_get_flash_node(nor); u32 dummy; @@ -161,11 +163,13 @@ static inline int spi_nor_read_dummy_cycles(struct spi_nor *nor) */ if (!of_property_read_u32(np, "spi-nor,ddr-quad-read-dummy", &dummy)) + pr_err("DUMMY CYCLE : %d !!!\n", dummy); return dummy; } case SPI_NOR_FAST: case SPI_NOR_DUAL: case SPI_NOR_QUAD: + case SPI_NOR_OCTAL: return 8; case SPI_NOR_NORMAL: return 0; @@ -907,6 +911,7 @@ static const struct flash_info spi_nor_ids[] = { { "n25q512ax3", INFO(0x20ba20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, { "n25q00", INFO(0x20ba21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, { "n25q00a", INFO(0x20bb21, 0, 64 * 1024, 2048, SECT_4K | USE_FSR | SPI_NOR_QUAD_READ) }, + {"mt35xu512aba", INFO(0x2c5b1a, 0, 128 * 1024, 512, SECT_4K | SPI_NOR_DDR_OCTAL_READ) }, /* PMC */ { "pm25lv512", INFO(0, 0, 32 * 1024, 2, SECT_4K_PMC) }, @@ -1486,8 +1491,11 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) if (info->flags & SPI_NOR_NO_FR) nor->flash_read = SPI_NOR_NORMAL; - /* DDR Quad/Quad/Dual-read mode takes precedence over fast/normal */ - if (mode == SPI_NOR_DDR_QUAD && info->flags & SPI_NOR_DDR_QUAD_READ) { + /* DDR Octal/Quad/Dual-read mode takes precedence over fast/normal */ + if (mode == SPI_NOR_DDR_OCTAL && info->flags & SPI_NOR_DDR_OCTAL_READ) { + nor->flash_read = SPI_NOR_DDR_OCTAL; + } else if (mode == SPI_NOR_DDR_QUAD && + info->flags & SPI_NOR_DDR_QUAD_READ) { ret = set_ddr_quad_mode(nor, info); if (ret) { dev_err(dev, "DDR quad mode not supported\n"); @@ -1507,6 +1515,9 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) /* Default commands */ switch (nor->flash_read) { + case SPI_NOR_DDR_OCTAL: + nor->read_opcode = SPINOR_OP_READ_1_1_8_D; + break; case SPI_NOR_DDR_QUAD: if (JEDEC_MFR(info) == CFI_MFR_AMD) { /* Spansion */ nor->read_opcode = SPINOR_OP_READ_1_4_4_D; @@ -1546,6 +1557,10 @@ int spi_nor_scan(struct spi_nor *nor, const char *name, enum read_mode mode) if (JEDEC_MFR(info) == SNOR_MFR_SPANSION) { /* Dedicated 4-byte command set */ switch (nor->flash_read) { + case SPI_NOR_DDR_OCTAL: + case SPI_NOR_OCTAL: + nor->read_opcode = SPINOR_OP_READ_1_1_8_D; + break; case SPI_NOR_DDR_QUAD: nor->read_opcode = SPINOR_OP_READ4_1_4_4_D; break; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index e73a46013eef..972609095414 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -46,8 +46,9 @@ #define SPINOR_OP_READ_FAST 0x0b /* Read data bytes (high frequency) */ #define SPINOR_OP_READ_1_1_2 0x3b /* Read data bytes (Dual SPI) */ #define SPINOR_OP_READ_1_1_4 0x6b /* Read data bytes (Quad SPI) */ -#define SPINOR_OP_READ_1_1_4_D 0x6d /* Read data bytes (DDR Quad SPI) */ -#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */ +#define SPINOR_OP_READ_1_1_4_D 0x6d /* Read data bytes (DDR Quad SPI) */ +#define SPINOR_OP_READ_1_4_4_D 0xed /* Read data bytes (DDR Quad SPI) */ +#define SPINOR_OP_READ_1_1_8_D 0x9d /* Read data bytes (Octal Output SPI) */ #define SPINOR_OP_PP 0x02 /* Page program (up to 256 bytes) */ #define SPINOR_OP_BE_4K 0x20 /* Erase 4KiB block */ #define SPINOR_OP_BE_4K_PMC 0xd7 /* Erase 4KiB block on PMC chips */ @@ -63,7 +64,7 @@ #define SPINOR_OP_READ4_FAST 0x0c /* Read data bytes (high frequency) */ #define SPINOR_OP_READ4_1_1_2 0x3c /* Read data bytes (Dual SPI) */ #define SPINOR_OP_READ4_1_1_4 0x6c /* Read data bytes (Quad SPI) */ -#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */ +#define SPINOR_OP_READ4_1_4_4_D 0xee /* Read data bytes (DDR Quad SPI) */ #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ @@ -112,6 +113,8 @@ enum read_mode { SPI_NOR_DUAL, SPI_NOR_QUAD, SPI_NOR_DDR_QUAD, + SPI_NOR_OCTAL, + SPI_NOR_DDR_OCTAL, }; #define SPI_NOR_MAX_CMD_SIZE 8