From: Haibo Chen Date: Tue, 28 Jul 2026 10:18:09 +0000 (+0800) Subject: spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b4bde5cfff8e43e948219f0a598e4bf057ecfba4;p=thirdparty%2Flinux.git spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL In nxp_fspi_select_mem() the RX sample clock source (MCR0[RXCLKSRC]) and the DLL control registers (DLLxCR) are reconfigured while the FlexSPI module is still enabled. According to the FlexSPI reference manual initialization sequence, MCR0 and the DLL control registers should be programmed while the module is in stop mode, i.e. with MCR0[MDIS] set to 1, and the module re-enabled (MCR0[MDIS] = 0) afterwards. Wrap the RX sample clock source selection and the DLL calibration/ override reconfiguration in a stop-mode window to align with the RM and avoid reconfiguring timing-critical registers while the module is active. Signed-off-by: Haibo Chen Reviewed-by: Frank Li Link: https://patch.msgid.link/20260728-fspi-clock-v2-2-dbe786a4a6eb@nxp.com Signed-off-by: Mark Brown --- diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c index 39c1eaaf9e0a..54355295f919 100644 --- a/drivers/spi/spi-nxp-fspi.c +++ b/drivers/spi/spi-nxp-fspi.c @@ -867,6 +867,7 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, unsigned long rate = op->max_freq; int ret; uint64_t size_kb; + u32 reg; /* * Return when following condition all meet, @@ -896,6 +897,15 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, dev_dbg(f->dev, "Target device [CS:%x] selected\n", spi_get_chipselect(spi, 0)); + /* + * Per the FlexSPI reference manual (initialization sequence), MCR0 and + * the DLL control registers should be configured while the module is in + * stop mode (MCR0[MDIS] = 1). Enter stop mode before reconfiguring the + * RX sample clock source and the DLL, then exit stop mode afterwards. + */ + reg = fspi_readl(f, f->iobase + FSPI_MCR0); + fspi_writel(f, reg | FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0); + nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr); rate = min(f->max_rate, op->max_freq); @@ -928,6 +938,10 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi, else nxp_fspi_dll_override(f); + /* Exit stop mode now that MCR0 and the DLL have been reconfigured. */ + reg = fspi_readl(f, f->iobase + FSPI_MCR0); + fspi_writel(f, reg & ~FSPI_MCR0_MDIS, f->iobase + FSPI_MCR0); + f->pre_op_rate = op->max_freq; f->selected = spi_get_chipselect(spi, 0);