Commit f6910679 authored by Frieder Schrempf's avatar Frieder Schrempf Committed by Mark Brown

spi: spi-fsl-qspi: Clear TDH bits in FLSHCR register

Later versions of the QSPI controller (e.g. in i.MX6UL/ULL and i.MX7)
seem to have an additional TDH setting in the FLSHCR register, that
needs to be set in accordance with the access mode that is used (DDR
or SDR).

Previous bootstages such as BootROM or bootloader might have used the
DDR mode to access the flash. As we currently only use SDR mode, we
need to make sure the TDH bits are cleared upon initialization.

Fixes: 84d04318 ("spi: Add a driver for the Freescale/NXP QuadSPI controller")
Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarFrieder Schrempf <frieder.schrempf@kontron.de>
Acked-by: default avatarHan Xu <han.xu@nxp.com>
Link: https://lore.kernel.org/r/20191007071933.26786-1-frieder.schrempf@kontron.deSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 5d2af8bc
...@@ -63,6 +63,11 @@ ...@@ -63,6 +63,11 @@
#define QUADSPI_IPCR 0x08 #define QUADSPI_IPCR 0x08
#define QUADSPI_IPCR_SEQID(x) ((x) << 24) #define QUADSPI_IPCR_SEQID(x) ((x) << 24)
#define QUADSPI_FLSHCR 0x0c
#define QUADSPI_FLSHCR_TCSS_MASK GENMASK(3, 0)
#define QUADSPI_FLSHCR_TCSH_MASK GENMASK(11, 8)
#define QUADSPI_FLSHCR_TDH_MASK GENMASK(17, 16)
#define QUADSPI_BUF3CR 0x1c #define QUADSPI_BUF3CR 0x1c
#define QUADSPI_BUF3CR_ALLMST_MASK BIT(31) #define QUADSPI_BUF3CR_ALLMST_MASK BIT(31)
#define QUADSPI_BUF3CR_ADATSZ(x) ((x) << 8) #define QUADSPI_BUF3CR_ADATSZ(x) ((x) << 8)
...@@ -95,6 +100,9 @@ ...@@ -95,6 +100,9 @@
#define QUADSPI_FR 0x160 #define QUADSPI_FR 0x160
#define QUADSPI_FR_TFF_MASK BIT(0) #define QUADSPI_FR_TFF_MASK BIT(0)
#define QUADSPI_RSER 0x164
#define QUADSPI_RSER_TFIE BIT(0)
#define QUADSPI_SPTRCLR 0x16c #define QUADSPI_SPTRCLR 0x16c
#define QUADSPI_SPTRCLR_IPPTRC BIT(8) #define QUADSPI_SPTRCLR_IPPTRC BIT(8)
#define QUADSPI_SPTRCLR_BFPTRC BIT(0) #define QUADSPI_SPTRCLR_BFPTRC BIT(0)
...@@ -112,9 +120,6 @@ ...@@ -112,9 +120,6 @@
#define QUADSPI_LCKER_LOCK BIT(0) #define QUADSPI_LCKER_LOCK BIT(0)
#define QUADSPI_LCKER_UNLOCK BIT(1) #define QUADSPI_LCKER_UNLOCK BIT(1)
#define QUADSPI_RSER 0x164
#define QUADSPI_RSER_TFIE BIT(0)
#define QUADSPI_LUT_BASE 0x310 #define QUADSPI_LUT_BASE 0x310
#define QUADSPI_LUT_OFFSET (SEQID_LUT * 4 * 4) #define QUADSPI_LUT_OFFSET (SEQID_LUT * 4 * 4)
#define QUADSPI_LUT_REG(idx) \ #define QUADSPI_LUT_REG(idx) \
...@@ -181,6 +186,12 @@ ...@@ -181,6 +186,12 @@
*/ */
#define QUADSPI_QUIRK_BASE_INTERNAL BIT(4) #define QUADSPI_QUIRK_BASE_INTERNAL BIT(4)
/*
* Controller uses TDH bits in register QUADSPI_FLSHCR.
* They need to be set in accordance with the DDR/SDR mode.
*/
#define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5)
struct fsl_qspi_devtype_data { struct fsl_qspi_devtype_data {
unsigned int rxfifo; unsigned int rxfifo;
unsigned int txfifo; unsigned int txfifo;
...@@ -209,7 +220,8 @@ static const struct fsl_qspi_devtype_data imx7d_data = { ...@@ -209,7 +220,8 @@ static const struct fsl_qspi_devtype_data imx7d_data = {
.rxfifo = SZ_128, .rxfifo = SZ_128,
.txfifo = SZ_512, .txfifo = SZ_512,
.ahb_buf_size = SZ_1K, .ahb_buf_size = SZ_1K,
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
QUADSPI_QUIRK_USE_TDH_SETTING,
.little_endian = true, .little_endian = true,
}; };
...@@ -217,7 +229,8 @@ static const struct fsl_qspi_devtype_data imx6ul_data = { ...@@ -217,7 +229,8 @@ static const struct fsl_qspi_devtype_data imx6ul_data = {
.rxfifo = SZ_128, .rxfifo = SZ_128,
.txfifo = SZ_512, .txfifo = SZ_512,
.ahb_buf_size = SZ_1K, .ahb_buf_size = SZ_1K,
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK, .quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
QUADSPI_QUIRK_USE_TDH_SETTING,
.little_endian = true, .little_endian = true,
}; };
...@@ -275,6 +288,11 @@ static inline int needs_amba_base_offset(struct fsl_qspi *q) ...@@ -275,6 +288,11 @@ static inline int needs_amba_base_offset(struct fsl_qspi *q)
return !(q->devtype_data->quirks & QUADSPI_QUIRK_BASE_INTERNAL); return !(q->devtype_data->quirks & QUADSPI_QUIRK_BASE_INTERNAL);
} }
static inline int needs_tdh_setting(struct fsl_qspi *q)
{
return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING;
}
/* /*
* An IC bug makes it necessary to rearrange the 32-bit data. * An IC bug makes it necessary to rearrange the 32-bit data.
* Later chips, such as IMX6SLX, have fixed this bug. * Later chips, such as IMX6SLX, have fixed this bug.
...@@ -710,6 +728,16 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q) ...@@ -710,6 +728,16 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK, qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
base + QUADSPI_MCR); base + QUADSPI_MCR);
/*
* Previous boot stages (BootROM, bootloader) might have used DDR
* mode and did not clear the TDH bits. As we currently use SDR mode
* only, clear the TDH bits if necessary.
*/
if (needs_tdh_setting(q))
qspi_writel(q, qspi_readl(q, base + QUADSPI_FLSHCR) &
~QUADSPI_FLSHCR_TDH_MASK,
base + QUADSPI_FLSHCR);
reg = qspi_readl(q, base + QUADSPI_SMPR); reg = qspi_readl(q, base + QUADSPI_SMPR);
qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
| QUADSPI_SMPR_FSPHS_MASK | QUADSPI_SMPR_FSPHS_MASK
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment