From f53c776d972a4f5b3fb126236689d6678c8d76a4 Mon Sep 17 00:00:00 2001 From: Michael Jung Date: Thu, 28 Jul 2022 11:44:02 +0200 Subject: [PATCH] w25qxxxjv.c: Ensure Quad SPI mode is enabled Certain variants of the W25QxxxJV Quad SPI NOR flash ICs have the Quad SPI mode disabled after reset. As the w25qxxxjv driver is operating the device in Quad SPI mode, make sure it gets enabled if required during device initialization. Signed-off-by: Michael Jung --- drivers/mtd/w25qxxxjv.c | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/w25qxxxjv.c b/drivers/mtd/w25qxxxjv.c index 4f289bd380..b84fb9f971 100644 --- a/drivers/mtd/w25qxxxjv.c +++ b/drivers/mtd/w25qxxxjv.c @@ -173,6 +173,12 @@ #define STATUS_SRP_UNLOCKED (0 << 7) /* see blow for details */ #define STATUS_SRP_LOCKED (1 << 7) /* see blow for details */ +/* Status register 2 bit definitions */ + +#define STATUS2_QE_MASK (1 << 1) /* Bit 1: Quad Enable (QE) */ +#define STATUS2_QE_DISABLED (0 << 1) /* 0 = Standard/Dual SPI modes */ +#define STATUS2_QE_ENABLED (1 << 1) /* 1 = Standard/Dual/Quad modes */ + /* Some chips have four protect bits */ /* Bits 2-5: Block protect bits */ @@ -353,6 +359,7 @@ static void w25qxxxjv_write_volcfg(FAR struct w25qxxxjv_dev_s *priv); #endif static void w25qxxxjv_write_enable(FAR struct w25qxxxjv_dev_s *priv); static void w25qxxxjv_write_disable(FAR struct w25qxxxjv_dev_s *priv); +static void w25qxxxjv_quad_enable(FAR struct w25qxxxjv_dev_s *priv); static int w25qxxxjv_readid(FAR struct w25qxxxjv_dev_s *priv); static int w25qxxxjv_protect(FAR struct w25qxxxjv_dev_s *priv, @@ -594,6 +601,29 @@ static void w25qxxxjv_write_disable(FAR struct w25qxxxjv_dev_s *priv) while ((status & STATUS_WEL_MASK) != STATUS_WEL_DISABLED); } +/**************************************************************************** + * Name: w25qxxxjv_quad_enable + ****************************************************************************/ + +static void w25qxxxjv_quad_enable(FAR struct w25qxxxjv_dev_s *priv) +{ + w25qxxxjv_command_read(priv->qspi, W25QXXXJV_READ_STATUS_2, + (FAR void *)priv->cmdbuf, 1); + + if ((priv->cmdbuf[0] & STATUS2_QE_MASK) != STATUS2_QE_ENABLED) + { + w25qxxxjv_write_enable(priv); + + priv->cmdbuf[0] &= ~STATUS2_QE_MASK; + priv->cmdbuf[1] |= STATUS2_QE_ENABLED; + + w25qxxxjv_command_write(priv->qspi, W25QXXXJV_WRITE_STATUS_2, + (FAR const void *)priv->cmdbuf, 1); + + w25qxxxjv_write_disable(priv); + } +} + /**************************************************************************** * Name: w25qxxxjv_readid ****************************************************************************/ @@ -976,8 +1006,8 @@ static int w25qxxxjv_write_page(struct w25qxxxjv_dev_s *priv, if (ret < 0) { - ferr("ERROR: QSPI_MEMORY failed writing address=%06x\n", - address); + ferr("ERROR: QSPI_MEMORY failed writing address=%06jx\n", + (uintmax_t)address); return ret; } @@ -1583,6 +1613,10 @@ FAR struct mtd_dev_s *w25qxxxjv_initialize(FAR struct qspi_dev_s *qspi, } } + /* Enable Quad SPI mode, if not already enabled. */ + + w25qxxxjv_quad_enable(priv); + #ifdef CONFIG_W25QXXXJV_SECTOR512 /* Simulate a 512 byte sector */ /* Allocate a buffer for the erase block cache */