Skip to content

Commit c69b17d

Browse files
fschrempfgregkh
authored andcommitted
spi: spi-fsl-qspi: Clear TDH bits in FLSHCR register
commit f691067 upstream. 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: 84d0431 ("spi: Add a driver for the Freescale/NXP QuadSPI controller") Cc: <[email protected]> Signed-off-by: Frieder Schrempf <[email protected]> Acked-by: Han Xu <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent d8d63ea commit c69b17d

File tree

1 file changed

+33
-5
lines changed

1 file changed

+33
-5
lines changed

drivers/spi/spi-fsl-qspi.c

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
#define QUADSPI_IPCR 0x08
6464
#define QUADSPI_IPCR_SEQID(x) ((x) << 24)
6565

66+
#define QUADSPI_FLSHCR 0x0c
67+
#define QUADSPI_FLSHCR_TCSS_MASK GENMASK(3, 0)
68+
#define QUADSPI_FLSHCR_TCSH_MASK GENMASK(11, 8)
69+
#define QUADSPI_FLSHCR_TDH_MASK GENMASK(17, 16)
70+
6671
#define QUADSPI_BUF3CR 0x1c
6772
#define QUADSPI_BUF3CR_ALLMST_MASK BIT(31)
6873
#define QUADSPI_BUF3CR_ADATSZ(x) ((x) << 8)
@@ -95,6 +100,9 @@
95100
#define QUADSPI_FR 0x160
96101
#define QUADSPI_FR_TFF_MASK BIT(0)
97102

103+
#define QUADSPI_RSER 0x164
104+
#define QUADSPI_RSER_TFIE BIT(0)
105+
98106
#define QUADSPI_SPTRCLR 0x16c
99107
#define QUADSPI_SPTRCLR_IPPTRC BIT(8)
100108
#define QUADSPI_SPTRCLR_BFPTRC BIT(0)
@@ -112,9 +120,6 @@
112120
#define QUADSPI_LCKER_LOCK BIT(0)
113121
#define QUADSPI_LCKER_UNLOCK BIT(1)
114122

115-
#define QUADSPI_RSER 0x164
116-
#define QUADSPI_RSER_TFIE BIT(0)
117-
118123
#define QUADSPI_LUT_BASE 0x310
119124
#define QUADSPI_LUT_OFFSET (SEQID_LUT * 4 * 4)
120125
#define QUADSPI_LUT_REG(idx) \
@@ -181,6 +186,12 @@
181186
*/
182187
#define QUADSPI_QUIRK_BASE_INTERNAL BIT(4)
183188

189+
/*
190+
* Controller uses TDH bits in register QUADSPI_FLSHCR.
191+
* They need to be set in accordance with the DDR/SDR mode.
192+
*/
193+
#define QUADSPI_QUIRK_USE_TDH_SETTING BIT(5)
194+
184195
struct fsl_qspi_devtype_data {
185196
unsigned int rxfifo;
186197
unsigned int txfifo;
@@ -209,15 +220,17 @@ static const struct fsl_qspi_devtype_data imx7d_data = {
209220
.rxfifo = SZ_128,
210221
.txfifo = SZ_512,
211222
.ahb_buf_size = SZ_1K,
212-
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK,
223+
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
224+
QUADSPI_QUIRK_USE_TDH_SETTING,
213225
.little_endian = true,
214226
};
215227

216228
static const struct fsl_qspi_devtype_data imx6ul_data = {
217229
.rxfifo = SZ_128,
218230
.txfifo = SZ_512,
219231
.ahb_buf_size = SZ_1K,
220-
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK,
232+
.quirks = QUADSPI_QUIRK_TKT253890 | QUADSPI_QUIRK_4X_INT_CLK |
233+
QUADSPI_QUIRK_USE_TDH_SETTING,
221234
.little_endian = true,
222235
};
223236

@@ -275,6 +288,11 @@ static inline int needs_amba_base_offset(struct fsl_qspi *q)
275288
return !(q->devtype_data->quirks & QUADSPI_QUIRK_BASE_INTERNAL);
276289
}
277290

291+
static inline int needs_tdh_setting(struct fsl_qspi *q)
292+
{
293+
return q->devtype_data->quirks & QUADSPI_QUIRK_USE_TDH_SETTING;
294+
}
295+
278296
/*
279297
* An IC bug makes it necessary to rearrange the 32-bit data.
280298
* Later chips, such as IMX6SLX, have fixed this bug.
@@ -710,6 +728,16 @@ static int fsl_qspi_default_setup(struct fsl_qspi *q)
710728
qspi_writel(q, QUADSPI_MCR_MDIS_MASK | QUADSPI_MCR_RESERVED_MASK,
711729
base + QUADSPI_MCR);
712730

731+
/*
732+
* Previous boot stages (BootROM, bootloader) might have used DDR
733+
* mode and did not clear the TDH bits. As we currently use SDR mode
734+
* only, clear the TDH bits if necessary.
735+
*/
736+
if (needs_tdh_setting(q))
737+
qspi_writel(q, qspi_readl(q, base + QUADSPI_FLSHCR) &
738+
~QUADSPI_FLSHCR_TDH_MASK,
739+
base + QUADSPI_FLSHCR);
740+
713741
reg = qspi_readl(q, base + QUADSPI_SMPR);
714742
qspi_writel(q, reg & ~(QUADSPI_SMPR_FSDLY_MASK
715743
| QUADSPI_SMPR_FSPHS_MASK

0 commit comments

Comments
 (0)