From 1b2a145d72c4202fc41b2af138b862a8be94b0f0 Mon Sep 17 00:00:00 2001 From: Dmitry Shifrin Date: Mon, 19 Mar 2018 11:29:21 +0300 Subject: [PATCH 07/12] spi-nor: Add s25fs512 flash support Signed-off-by: Dmitry Shifrin --- drivers/mtd/spi-nor/spi-nor.c | 31 ++++++++++++++++++++++++++++--- include/linux/mtd/spi-nor.h | 15 +++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c index d0fc165..1855bbe 100644 --- a/drivers/mtd/spi-nor/spi-nor.c +++ b/drivers/mtd/spi-nor/spi-nor.c @@ -75,6 +75,7 @@ struct flash_info { * bit. Must be used with * SPI_NOR_HAS_LOCK. */ +#define SPANSION_S512FS_QUIRK BIT(10) }; #define JEDEC_MFR(info) ((info)->id[0]) @@ -222,8 +223,18 @@ static inline int spi_nor_sr_ready(struct spi_nor *nor) int sr = read_sr(nor); if (sr < 0) return sr; - else - return !(sr & SR_WIP); + + if (nor->flags & SNOR_F_USE_CLSR && sr & (SR_E_ERR | SR_P_ERR)) { + if (sr & SR_E_ERR) + dev_err(nor->dev, "Erase Error occurred\n"); + else + dev_err(nor->dev, "Programming Error occurred\n"); + + nor->write_reg(nor, SPINOR_OP_CLSR, NULL, 0); + return -EIO; + } + + return !(sr & SR_WIP); } static inline int spi_nor_fsr_ready(struct spi_nor *nor) @@ -901,7 +912,21 @@ static const struct flash_info spi_nor_ids[] = { { "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, { "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) }, { "s25fl256s1", INFO(0x010219, 0x4d01, 64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, - { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + { "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, + + { + "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPANSION_S512FS_QUIRK) + }, + { + "s25fs128s0", INFO6(0x012018, 0x4d0381, 256 * 1024, 64, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPANSION_S512FS_QUIRK) + }, + { + "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256, + SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ | SECT_4K | SPANSION_S512FS_QUIRK) + }, + { "s70fl01gs", INFO(0x010221, 0x4d00, 256 * 1024, 256, 0) }, { "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64, 0) }, { "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256, 0) }, diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index c425c7b..99f7b2a 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -60,8 +60,10 @@ #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 0xec /* Read data bytes (Quad I/O SPI) */ #define SPINOR_OP_PP_4B 0x12 /* Page program (up to 256 bytes) */ #define SPINOR_OP_SE_4B 0xdc /* Sector erase (usually 64KiB) */ +#define SPINOR_OP_BE_4K_4B 0x21 /* Erase 4KiB block */ /* Used for SST flashes only. */ #define SPINOR_OP_BP 0x02 /* Byte program */ @@ -74,6 +76,7 @@ /* Used for Spansion flashes only. */ #define SPINOR_OP_BRWR 0x17 /* Bank register write */ +#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */ /* Used for Micron flashes only. */ #define SPINOR_OP_RD_EVCR 0x65 /* Read EVCR register */ @@ -88,6 +91,9 @@ #define SR_BP2 BIT(4) /* Block protect 2 */ #define SR_TB BIT(5) /* Top/Bottom protect */ #define SR_SRWD BIT(7) /* SR write protect */ +/* Spansion/Cypress specific status bits */ +#define SR_E_ERR BIT(5) +#define SR_P_ERR BIT(6) #define SR_QUAD_EN_MX BIT(6) /* Macronix Quad I/O */ @@ -119,6 +125,7 @@ enum spi_nor_ops { enum spi_nor_option_flags { SNOR_F_USE_FSR = BIT(0), SNOR_F_HAS_SR_TB = BIT(1), + SNOR_F_USE_CLSR = BIT(5), }; /** @@ -197,6 +204,14 @@ static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor) return mtd_get_of_node(&nor->mtd); } +static inline int spi_nor_get_read_addr_nbits(u8 opcode) +{ + if (opcode == SPINOR_OP_READ4_1_4_4) + return 4; + return 1; +} + + /** * spi_nor_scan() - scan the SPI NOR * @nor: the spi_nor structure -- 2.7.4