summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYe Li <ye.li@nxp.com>2017-05-10 09:52:42 -0500
committerYe Li <ye.li@nxp.com>2017-05-10 20:25:05 -0500
commit16270556212e6c7422e87f69572c90f1afe6998b (patch)
tree29a2dd490c79f615c38e732b7f80ff97ae234eb8
parentb4f74042d6095a9713a1e31ba5f4361de4a19b50 (diff)
downloadu-boot-imx-16270556212e6c7422e87f69572c90f1afe6998b.zip
u-boot-imx-16270556212e6c7422e87f69572c90f1afe6998b.tar.gz
u-boot-imx-16270556212e6c7422e87f69572c90f1afe6998b.tar.bz2
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>
-rw-r--r--drivers/spi/fsl_qspi.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index c27807d..6e511bc 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -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;