[U-Boot] [PATCH] mtd: qspi: support read the flag status in fspi driver

From: Han Xu han.xu@nxp.com
Support to read the flag status in driver to avoid the spi-nor framework wait_for_ready hang issue.
Signed-off-by: Han Xu han.xu@nxp.com --- drivers/spi/fsl_qspi.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 1987a72..ed0e649 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif #define SEQID_WRAR 13 #define SEQID_RDAR 14 +#define SEQID_RDFSR 15
/* QSPI CMD */ #define QSPI_CMD_PP 0x02 /* Page program (up to 256 bytes) */ @@ -57,6 +58,7 @@ DECLARE_GLOBAL_DATA_PTR; #define QSPI_CMD_CHIP_ERASE 0xc7 /* Erase whole flash chip */ #define QSPI_CMD_SE 0xd8 /* Sector erase (usually 64KiB) */ #define QSPI_CMD_RDID 0x9f /* Read JEDEC ID */ +#define QSPI_CMD_FLAG_SR 0x70 /* Read FLAG STATUS*/
/* Used for Micron, winbond and Macronix flashes */ #define QSPI_CMD_WREAR 0xc5 /* EAR register write */ @@ -230,6 +232,15 @@ static void qspi_set_lut(struct fsl_qspi_priv *priv) qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0);
+ /* Read Flag Status */ + lut_base = SEQID_RDFSR * 4; + qspi_write32(priv->flags, ®s->lut[lut_base], OPRND0(QSPI_CMD_FLAG_SR) | + PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) | + PAD1(LUT_PAD1) | INSTR1(LUT_READ)); + qspi_write32(priv->flags, ®s->lut[lut_base + 1], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 2], 0); + qspi_write32(priv->flags, ®s->lut[lut_base + 3], 0); + /* Erase a sector */ lut_base = SEQID_SE * 4; #ifdef CONFIG_SPI_FLASH_BAR @@ -740,6 +751,40 @@ static void qspi_op_rdsr(struct fsl_qspi_priv *priv, void *rxbuf, u32 len) qspi_write32(priv->flags, ®s->mcr, mcr_reg); }
+static void qspi_op_rdfsr(struct fsl_qspi_priv *priv, void *rxbuf, u32 len) +{ + struct fsl_qspi_regs *regs = priv->regs; + u32 mcr_reg, reg, data; + + mcr_reg = qspi_read32(priv->flags, ®s->mcr); + qspi_write32(priv->flags, ®s->mcr, + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK | + mcr_reg); + qspi_write32(priv->flags, ®s->rbct, QSPI_RBCT_RXBRD_USEIPS); + + qspi_write32(priv->flags, ®s->sfar, priv->cur_amba_base); + + qspi_write32(priv->flags, ®s->ipcr, + (SEQID_RDFSR << QSPI_IPCR_SEQID_SHIFT) | 0); + while (qspi_read32(priv->flags, ®s->sr) & QSPI_SR_BUSY_MASK) + ; + + while (1) { + reg = qspi_read32(priv->flags, ®s->rbsr); + if (reg & QSPI_RBSR_RDBFL_MASK) { + data = qspi_read32(priv->flags, ®s->rbdr[0]); + data = qspi_endian_xchg(data); + memcpy(rxbuf, &data, len); + qspi_write32(priv->flags, ®s->mcr, + qspi_read32(priv->flags, ®s->mcr) | + QSPI_MCR_CLR_RXF_MASK); + break; + } + } + + qspi_write32(priv->flags, ®s->mcr, mcr_reg); +} + static void qspi_op_erase(struct fsl_qspi_priv *priv) { struct fsl_qspi_regs *regs = priv->regs; @@ -825,6 +870,8 @@ int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen, qspi_op_rdid(priv, din, bytes); else if (priv->cur_seqid == QSPI_CMD_RDSR) qspi_op_rdsr(priv, din, bytes); + else if (priv->cur_seqid == QSPI_CMD_FLAG_SR) + qspi_op_rdfsr(priv, din, bytes); #ifdef CONFIG_SPI_FLASH_BAR else if ((priv->cur_seqid == QSPI_CMD_BRRD) || (priv->cur_seqid == QSPI_CMD_RDEAR)) {

On Mon, Jan 7, 2019 at 2:24 PM Ye Li ye.li@nxp.com wrote:
From: Han Xu han.xu@nxp.com
Support to read the flag status in driver to avoid the spi-nor framework wait_for_ready hang issue.
Signed-off-by: Han Xu han.xu@nxp.com
drivers/spi/fsl_qspi.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 1987a72..ed0e649 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif #define SEQID_WRAR 13 #define SEQID_RDAR 14 +#define SEQID_RDFSR 15
/* QSPI CMD */ #define QSPI_CMD_PP 0x02 /* Page program (up to 256 bytes) */ @@ -57,6 +58,7 @@ DECLARE_GLOBAL_DATA_PTR; #define QSPI_CMD_CHIP_ERASE 0xc7 /* Erase whole flash chip */ #define QSPI_CMD_SE 0xd8 /* Sector erase (usually 64KiB) */ #define QSPI_CMD_RDID 0x9f /* Read JEDEC ID */ +#define QSPI_CMD_FLAG_SR 0x70 /* Read FLAG STATUS*/
NAK, need to handle this from flash side. better keep working on that front.

Hi,
On 09/02/19 10:59 PM, Jagan Teki wrote:
On Mon, Jan 7, 2019 at 2:24 PM Ye Li ye.li@nxp.com wrote:
From: Han Xu han.xu@nxp.com
Support to read the flag status in driver to avoid the spi-nor framework wait_for_ready hang issue.
Signed-off-by: Han Xu han.xu@nxp.com
drivers/spi/fsl_qspi.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+)
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c index 1987a72..ed0e649 100644 --- a/drivers/spi/fsl_qspi.c +++ b/drivers/spi/fsl_qspi.c @@ -47,6 +47,7 @@ DECLARE_GLOBAL_DATA_PTR; #endif #define SEQID_WRAR 13 #define SEQID_RDAR 14 +#define SEQID_RDFSR 15
/* QSPI CMD */ #define QSPI_CMD_PP 0x02 /* Page program (up to 256 bytes) */ @@ -57,6 +58,7 @@ DECLARE_GLOBAL_DATA_PTR; #define QSPI_CMD_CHIP_ERASE 0xc7 /* Erase whole flash chip */ #define QSPI_CMD_SE 0xd8 /* Sector erase (usually 64KiB) */ #define QSPI_CMD_RDID 0x9f /* Read JEDEC ID */ +#define QSPI_CMD_FLAG_SR 0x70 /* Read FLAG STATUS*/
NAK, need to handle this from flash side. better keep working on that front.
U-Boot now supports spi-mem abstraction just like kernel. Could you move fsl_qspi to use spi-mem APIs to get rid of using opcodes directly within the driver?
participants (3)
-
Jagan Teki
-
Vignesh R
-
Ye Li