Commit 767faa948d2d140b6d56ee505f81f8f57c045a3d

Authored by Han Xu
1 parent 558ec9aed3

MLK-17656: mtd: qspi: support read the flag status in fspi driver

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>

Showing 1 changed file with 47 additions and 0 deletions Side-by-side Diff

drivers/spi/fsl_qspi.c
... ... @@ -47,6 +47,7 @@
47 47 #endif
48 48 #define SEQID_WRAR 13
49 49 #define SEQID_RDAR 14
  50 +#define SEQID_RDFSR 15
50 51  
51 52 /* QSPI CMD */
52 53 #define QSPI_CMD_PP 0x02 /* Page program (up to 256 bytes) */
... ... @@ -57,6 +58,7 @@
57 58 #define QSPI_CMD_CHIP_ERASE 0xc7 /* Erase whole flash chip */
58 59 #define QSPI_CMD_SE 0xd8 /* Sector erase (usually 64KiB) */
59 60 #define QSPI_CMD_RDID 0x9f /* Read JEDEC ID */
  61 +#define QSPI_CMD_FLAG_SR 0x70 /* Read FLAG STATUS*/
60 62  
61 63 /* Used for Micron, winbond and Macronix flashes */
62 64 #define QSPI_CMD_WREAR 0xc5 /* EAR register write */
... ... @@ -219,6 +221,15 @@
219 221 qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
220 222 qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
221 223  
  224 + /* Read Flag Status */
  225 + lut_base = SEQID_RDFSR * 4;
  226 + qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_FLAG_SR) |
  227 + PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
  228 + PAD1(LUT_PAD1) | INSTR1(LUT_READ));
  229 + qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
  230 + qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
  231 + qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
  232 +
222 233 /* Erase a sector */
223 234 lut_base = SEQID_SE * 4;
224 235 #ifdef CONFIG_SPI_FLASH_BAR
... ... @@ -742,6 +753,40 @@
742 753 qspi_write32(priv->flags, &regs->mcr, mcr_reg);
743 754 }
744 755  
  756 +static void qspi_op_rdfsr(struct fsl_qspi_priv *priv, void *rxbuf, u32 len)
  757 +{
  758 + struct fsl_qspi_regs *regs = priv->regs;
  759 + u32 mcr_reg, reg, data;
  760 +
  761 + mcr_reg = qspi_read32(priv->flags, &regs->mcr);
  762 + qspi_write32(priv->flags, &regs->mcr,
  763 + QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
  764 + mcr_reg);
  765 + qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
  766 +
  767 + qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
  768 +
  769 + qspi_write32(priv->flags, &regs->ipcr,
  770 + (SEQID_RDFSR << QSPI_IPCR_SEQID_SHIFT) | 0);
  771 + while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
  772 + ;
  773 +
  774 + while (1) {
  775 + reg = qspi_read32(priv->flags, &regs->rbsr);
  776 + if (reg & QSPI_RBSR_RDBFL_MASK) {
  777 + data = qspi_read32(priv->flags, &regs->rbdr[0]);
  778 + data = qspi_endian_xchg(data);
  779 + memcpy(rxbuf, &data, len);
  780 + qspi_write32(priv->flags, &regs->mcr,
  781 + qspi_read32(priv->flags, &regs->mcr) |
  782 + QSPI_MCR_CLR_RXF_MASK);
  783 + break;
  784 + }
  785 + }
  786 +
  787 + qspi_write32(priv->flags, &regs->mcr, mcr_reg);
  788 +}
  789 +
745 790 static void qspi_op_erase(struct fsl_qspi_priv *priv)
746 791 {
747 792 struct fsl_qspi_regs *regs = priv->regs;
... ... @@ -825,6 +870,8 @@
825 870 qspi_op_rdid(priv, din, bytes);
826 871 else if (priv->cur_seqid == QSPI_CMD_RDSR)
827 872 qspi_op_rdsr(priv, din, bytes);
  873 + else if (priv->cur_seqid == QSPI_CMD_FLAG_SR)
  874 + qspi_op_rdfsr(priv, din, bytes);
828 875 #ifdef CONFIG_SPI_FLASH_BAR
829 876 else if ((priv->cur_seqid == QSPI_CMD_BRRD) ||
830 877 (priv->cur_seqid == QSPI_CMD_RDEAR)) {