Browse Source

MLK-14878 qspi: Fix issue when enabling DDR mode

There are two problems in enabling DDR mode in this new driver:
1. The TDH bits in FLSHCR register should be set to 1. Otherwise, the TX DDR delay logic
   won't be enabled. Since u-boot driver does not have DDR commands in LUT. So this won't
   cause explicit problem.
2. When doing read/write/readid/erase operations, the MCR register is overwritten, the bits
   like DDR_EN are cleared during these operations.  When we using DDR mode QSPI boot, the TDH bit
   is set to 1 by ROM. if the DDR_EN is cleared, there is no clk2x output for TX data shift.
   So these operations will fail.
   The explicit problem is users may get "SF: unrecognized JEDEC id bytes: ff, ff, ff" error
   after using DDR mode QSPI boot on 6UL/ULL EVK boards.

Signed-off-by: Ye Li <ye.li@nxp.com>
imx_v2017.03_4.9.11_1.0.0_ga
Ye Li 4 years ago
parent
commit
1627055621
1 changed files with 13 additions and 7 deletions
  1. +13
    -7
      drivers/spi/fsl_qspi.c

+ 13
- 7
drivers/spi/fsl_qspi.c View File

@ -393,7 +393,7 @@ static inline void qspi_ahb_read(struct fsl_qspi_priv *priv, u8 *rxbuf, int len)
qspi_write32(priv->flags, &regs->mcr,
QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
mcr_reg);
rx_addr = (void *)(uintptr_t)(priv->cur_amba_base + priv->sf_addr);
/* Read out the data directly from the AHB buffer. */
@ -424,6 +424,12 @@ static void qspi_enable_ddr_mode(struct fsl_qspi_priv *priv)
reg |= BIT(29);
qspi_write32(priv->flags, &regs->mcr, reg);
/* Enable the TDH to 1 for i.mx6ul and mx7d, it is reserved on other platforms */
reg = qspi_read32(priv->flags, &regs->flshcr);
reg &= ~(BIT(17));
reg |= BIT(16);
qspi_write32(priv->flags, &regs->flshcr, reg);
}
#endif
@ -485,7 +491,7 @@ static void qspi_op_rdbank(struct fsl_qspi_priv *priv, u8 *rxbuf, u32 len)
mcr_reg = qspi_read32(priv->flags, &regs->mcr);
qspi_write32(priv->flags, &regs->mcr,
QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
mcr_reg);
qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
@ -528,7 +534,7 @@ static void qspi_op_rdid(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
mcr_reg = qspi_read32(priv->flags, &regs->mcr);
qspi_write32(priv->flags, &regs->mcr,
QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
mcr_reg);
qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
@ -572,7 +578,7 @@ static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
mcr_reg = qspi_read32(priv->flags, &regs->mcr);
qspi_write32(priv->flags, &regs->mcr,
QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
mcr_reg);
qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
to_or_from = priv->sf_addr + priv->cur_amba_base;
@ -625,7 +631,7 @@ static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len)
mcr_reg = qspi_read32(priv->flags, &regs->mcr);
qspi_write32(priv->flags, &regs->mcr,
QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
mcr_reg);
qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
status_reg = 0;
@ -710,7 +716,7 @@ static void qspi_op_rdsr(struct fsl_qspi_priv *priv, void *rxbuf, u32 len)
mcr_reg = qspi_read32(priv->flags, &regs->mcr);
qspi_write32(priv->flags, &regs->mcr,
QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
mcr_reg);
qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
@ -745,7 +751,7 @@ static void qspi_op_erase(struct fsl_qspi_priv *priv)
mcr_reg = qspi_read32(priv->flags, &regs->mcr);
qspi_write32(priv->flags, &regs->mcr,
QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
mcr_reg);
qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
to_or_from = priv->sf_addr + priv->cur_amba_base;


Loading…
Cancel
Save