diff options
Diffstat (limited to 'target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch')
-rw-r--r-- | target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch b/target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch new file mode 100644 index 0000000000..087b6715d0 --- /dev/null +++ b/target/linux/socfpga/patches-4.4/0019-mtd-spi-nor-fix-support-of-Macronix-memories.patch @@ -0,0 +1,139 @@ +From 4e094634d1995e279f8bc5eb92463295cb894c76 Mon Sep 17 00:00:00 2001 +From: Cyrille Pitchen <cyrille.pitchen@atmel.com> +Date: Fri, 8 Jan 2016 17:02:16 +0100 +Subject: [PATCH 19/33] mtd: spi-nor: fix support of Macronix memories + +This patch fixes the support of Macronix memories. Especially we avoid +updating the Status Register when not needed as the Quad Enable (QE) bit +is a non-volatile bit. + +Also we add comments to explain why we use some Fast Read op codes rather +than others. + +Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com> +--- + drivers/mtd/spi-nor/spi-nor.c | 81 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 72 insertions(+), 9 deletions(-) + +diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c +index 889af12..1b1f5a6 100644 +--- a/drivers/mtd/spi-nor/spi-nor.c ++++ b/drivers/mtd/spi-nor/spi-nor.c +@@ -1107,6 +1107,11 @@ static int macronix_quad_enable(struct spi_nor *nor) + val = read_sr(nor); + if (val < 0) + return val; ++ ++ if (likely(val & SR_QUAD_EN_MX)) ++ return 0; ++ dev_warn(nor->dev, "Macronix Quad mode disabled, enable it\n"); ++ + write_enable(nor); + + write_sr(nor, val | SR_QUAD_EN_MX); +@@ -1161,21 +1166,73 @@ static int spansion_quad_enable(struct spi_nor *nor) + return 0; + } + ++static int macronix_set_quad_mode(struct spi_nor *nor) ++{ ++ int status; ++ ++ /* Check whether the QPI mode is enabled. */ ++ if (nor->read_proto == SNOR_PROTO_4_4_4) { ++ /* ++ * Since the QPI mode is enabled, the Quad Enabled (QE) ++ * non-volatile bit is already set. ++ * However in QPI mode, only the Fast Read 1-4-4 (0xeb) ++ * op code is supported. ++ * WARNING: we should take care about the performance ++ * enhance toggling bits P0-P7 written during the ++ * dummy/mode cycles to avoid entering the continuous ++ * read (performance enhance) mode by mistake! ++ */ ++ nor->read_opcode = SPINOR_OP_READ_1_4_4; ++ return 0; ++ } ++ ++ /* ++ * The QPI mode is disabled but we still need to set the QE bit: ++ * this disables the reset and write protect features and ++ * frees the associated pins so they can be used as the 3rd ++ * and 4th I/O lines required by Quad SPI commands. ++ * Also we'd rather use the Fast Read 1-1-4 (0x6b) op code than ++ * the Fast Read 1-4-4 (0xeb) op code so we don't care about ++ * entering the continuous read mode by mistake if some ++ * performance enhance toggling bits P0-P7 were written during ++ * dummy/mode cycles. ++ */ ++ status = macronix_quad_enable(nor); ++ if (status) { ++ dev_err(nor->dev, "Macronix quad-read not enabled\n"); ++ return status; ++ } ++ nor->read_proto = SNOR_PROTO_1_1_4; ++ nor->read_opcode = SPINOR_OP_READ_1_1_4; ++ return 0; ++} ++ ++/* ++ * For both Macronix Dual and Single modes, we don't care about the value of ++ * the Quad Enabled (QE) bit since the memory still replies to Dual or Single ++ * SPI commands. ++ */ ++ ++static int macronix_set_dual_mode(struct spi_nor *nor) ++{ ++ nor->read_proto = SNOR_PROTO_1_1_2; ++ nor->read_opcode = SPINOR_OP_READ_1_1_2; ++ return 0; ++} ++ ++static int macronix_set_single_mode(struct spi_nor *nor) ++{ ++ nor->read_proto = SNOR_PROTO_1_1_1; ++ return 0; ++} ++ + static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info) + { + int status; + + switch (JEDEC_MFR(info)) { + case SNOR_MFR_MACRONIX: +- status = macronix_quad_enable(nor); +- if (status) { +- dev_err(nor->dev, "Macronix quad-read not enabled\n"); +- return -EINVAL; +- } +- /* Check whether Macronix QPI mode is enabled. */ +- if (nor->read_proto != SNOR_PROTO_4_4_4) +- nor->read_proto = SNOR_PROTO_1_1_4; +- break; ++ return macronix_set_quad_mode(nor); + + case SNOR_MFR_MICRON: + /* Check whether Micron Quad mode is enabled. */ +@@ -1203,6 +1260,9 @@ static int set_quad_mode(struct spi_nor *nor, const struct flash_info *info) + static int set_dual_mode(struct spi_nor *nor, const struct flash_info *info) + { + switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_MACRONIX: ++ return macronix_set_dual_mode(nor); ++ + case SNOR_MFR_MICRON: + /* Check whether Micron Dual mode is enabled. */ + if (nor->read_proto != SNOR_PROTO_2_2_2) +@@ -1221,6 +1281,9 @@ static int set_dual_mode(struct spi_nor *nor, const struct flash_info *info) + static int set_single_mode(struct spi_nor *nor, const struct flash_info *info) + { + switch (JEDEC_MFR(info)) { ++ case SNOR_MFR_MACRONIX: ++ return macronix_set_single_mode(nor); ++ + default: + nor->read_proto = SNOR_PROTO_1_1_1; + break; +-- +2.8.1 + |