123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- 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
|