mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi
@ 2026-07-28 10:18 haibo.chen
  2026-07-28 10:18 ` [PATCH v2 1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs haibo.chen
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: haibo.chen @ 2026-07-28 10:18 UTC (permalink / raw)
  To: Han Xu, Yogesh Gaur, Mark Brown; +Cc: linux-spi, imx, linux-kernel, Haibo Chen

Patch 1 introduce per-SoC clock rate limits for both SDR and DTR modes
        by adding max_sdr_rate and max_dtr_rate to nxp_fspi_devtype_data.
Patch 2 enter stop mode before reconfiguring MCR0 and DLL to follow
	FlexSPI reference manual initialization sequence
Patch 3 propagate clock reconfig failures in nxp_fspi_select_mem()

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
Changes in v2:
- Patch1: rework the commit log by Frank's comment.
- Add Patch2 and Patch 3 accroding to AI Sashiko's comment.
- Link to v1: https://lore.kernel.org/r/20260727-fspi-clock-v1-1-f4f3be6c366d@nxp.com

---
Haibo Chen (3):
      spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs
      spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL
      spi: spi-nxp-fspi: propagate clock reconfig failures in nxp_fspi_select_mem()

 drivers/spi/spi-nxp-fspi.c | 129 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 119 insertions(+), 10 deletions(-)
---
base-commit: c5e32e86ca02b003f86e095d379b38148999293d
change-id: 20260727-fspi-clock-adcae0c35283

Best regards,
-- 
Haibo Chen <haibo.chen@nxp.com>


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs
  2026-07-28 10:18 [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi haibo.chen
@ 2026-07-28 10:18 ` haibo.chen
  2026-07-28 15:14   ` Frank Li
  2026-07-28 10:18 ` [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL haibo.chen
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: haibo.chen @ 2026-07-28 10:18 UTC (permalink / raw)
  To: Han Xu, Yogesh Gaur, Mark Brown; +Cc: linux-spi, imx, linux-kernel, Haibo Chen

From: Haibo Chen <haibo.chen@nxp.com>

The commit f43579ef3500 ("spi: spi-nxp-fspi: limit the clock rate for
different sample clock source selection") introduced a global 166MHz
cap for DTR mode (RXCLKSRC=3), based on the i.MX8MN datasheet timing
specification (Section 3.9.9, page 65).

After reviewing the FlexSPI timing parameters in the datasheets for all
supported SoCs, the following corrections and additions are needed:

1. SDR mode (RXCLKSRC=0) limits vary per SoC:
   - i.MX8MN/MM/MP/95: 66MHz  (IMX8MNCEC §3.9.9, IMX8MMCEC §3.9.10,
                                IMX8MPCEC, IMX95CEC Rev.8 §4.11.7)
   - i.MX8QXP/QM/DXL/ULP: 60MHz (IMX8QXPCEC, IMX8QMCEC, IMX8DXLCEC,
                                   IMX8ULPCEC §7.3.1 ND mode)
   - LX2160A: 100MHz            (LX2160ACEC FlexSPI timing parameters)

2. DTR mode (RXCLKSRC=3) limits vary per SoC:
   - i.MX8MN/MM/MP/ULP: 166MHz
   - i.MX8QXP/QM/DXL: 200MHz   (same FlexSPI IP across this family)
   - i.MX95: 200MHz             (IMX95CEC §4.11.7.3.2.3 Table 106)
   - LX2160A: DTR disabled      (FSPI_QUIRK_DISABLE_DTR)

Update related platform data with correct speed limation according
to datasheet.

Fixes: f43579ef3500 ("spi: spi-nxp-fspi: limit the clock rate for different sample clock source selection")
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
 drivers/spi/spi-nxp-fspi.c | 83 ++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 80 insertions(+), 3 deletions(-)

diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index d94a2a7b98d44db217ba96a8ce7df23e37a08ba4..6de6d432cdcb2ee383a02d72f20000045903e176 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -340,6 +340,18 @@ struct nxp_fspi_devtype_data {
 	unsigned int quirks;
 	unsigned int lut_num;
 	bool little_endian;
+	/*
+	 * The max clock rate (Hz) that FlexSPI can output to the device
+	 * in SDR mode (RXCLKSRC=0). Defaults to 66MHz if zero.
+	 * Some SoCs (e.g. LX2160A) support up to 100MHz in SDR mode.
+	 */
+	unsigned long max_sdr_rate;
+	/*
+	 * The max clock rate (Hz) that FlexSPI can output to the device
+	 * in DTR mode (RXCLKSRC=3). Defaults to 166MHz if zero.
+	 * Some SoCs (e.g. i.MX95, i.MX8QM, i.MX8DXL) support up to 200MHz.
+	 */
+	unsigned long max_dtr_rate;
 };
 
 static struct nxp_fspi_devtype_data lx2160a_data = {
@@ -349,6 +361,10 @@ static struct nxp_fspi_devtype_data lx2160a_data = {
 	.quirks = FSPI_QUIRK_DISABLE_DTR,
 	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
+	/*
+	 * LX2160ACEC: SDR RXCLKSRC=0 max 100MHz, DTR disabled via quirk.
+	 */
+	.max_sdr_rate = 100000000,
 };
 
 static struct nxp_fspi_devtype_data imx8mm_data = {
@@ -358,6 +374,21 @@ static struct nxp_fspi_devtype_data imx8mm_data = {
 	.quirks = 0,
 	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
+	/* IMX8MMCEC §3.9.10: SDR RXCLKSRC=0 max 66MHz, DDR RXCLKSRC=3 max 166MHz */
+	.max_sdr_rate = 66000000,
+	.max_dtr_rate = 166000000,
+};
+
+static struct nxp_fspi_devtype_data imx8mp_data = {
+	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
+	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
+	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
+	.quirks = 0,
+	.lut_num = 32,
+	.little_endian = true,  /* little-endian    */
+	/* IMX8MPCEC: SDR RXCLKSRC=0 max 66MHz, DDR RXCLKSRC=3 max 166MHz */
+	.max_sdr_rate = 66000000,
+	.max_dtr_rate = 166000000,
 };
 
 static struct nxp_fspi_devtype_data imx8qxp_data = {
@@ -367,6 +398,12 @@ static struct nxp_fspi_devtype_data imx8qxp_data = {
 	.quirks = 0,
 	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
+	/*
+	 * IMX8QXPCEC: SDR RXCLKSRC=0 max 60MHz, DDR RXCLKSRC=3 max 200MHz.
+	 * i.MX8QM and i.MX8DXL share the same FlexSPI IP and limits.
+	 */
+	.max_sdr_rate = 60000000,
+	.max_dtr_rate = 200000000,
 };
 
 static struct nxp_fspi_devtype_data imx8dxl_data = {
@@ -376,6 +413,12 @@ static struct nxp_fspi_devtype_data imx8dxl_data = {
 	.quirks = FSPI_QUIRK_USE_IP_ONLY,
 	.lut_num = 32,
 	.little_endian = true,  /* little-endian    */
+	/*
+	 * IMX8DXLCEC (i.MX 8XLite): SDR RXCLKSRC=0 max 60MHz,
+	 * DDR RXCLKSRC=3 max 200MHz.
+	 */
+	.max_sdr_rate = 60000000,
+	.max_dtr_rate = 200000000,
 };
 
 static struct nxp_fspi_devtype_data imx8ulp_data = {
@@ -385,6 +428,29 @@ static struct nxp_fspi_devtype_data imx8ulp_data = {
 	.quirks = 0,
 	.lut_num = 16,
 	.little_endian = true,  /* little-endian    */
+	/*
+	 * IMX8ULPCEC §7.3.1, Normal Drive (ND, 1.0V) mode:
+	 * SDR RXCLKSRC=0 max 60MHz, DDR RXCLKSRC=3 max 166MHz.
+	 * Note: Overdrive (OD, 1.05V) allows up to 180MHz DTR
+	 * but is not the default use case.
+	 */
+	.max_sdr_rate = 60000000,
+	.max_dtr_rate = 166000000,
+};
+
+static struct nxp_fspi_devtype_data imx95_data = {
+	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
+	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
+	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
+	.quirks = 0,
+	.lut_num = 32,
+	.little_endian = true,  /* little-endian    */
+	/*
+	 * IMX95CEC Rev.8 §4.11.7: SDR RXCLKSRC=0 max 66MHz,
+	 * DDR RXCLKSRC=3 max 200MHz (Nominal/Overdrive mode).
+	 */
+	.max_sdr_rate = 66000000,
+	.max_dtr_rate = 200000000,
 };
 
 struct nxp_fspi {
@@ -691,10 +757,20 @@ static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f,
 	reg = fspi_readl(f, f->iobase + FSPI_MCR0);
 	if (op_is_dtr) {
 		reg |= FSPI_MCR0_RXCLKSRC(3);
-		f->max_rate = 166000000;
+		/*
+		 * Use the SoC-specific DTR max rate if provided, otherwise
+		 * fall back to 166MHz (limit from IMX8MN datasheet §3.9.9).
+		 */
+		f->max_rate = f->devtype_data->max_dtr_rate ?
+			      f->devtype_data->max_dtr_rate : 166000000;
 	} else {	/*select mode 0 */
 		reg &= ~FSPI_MCR0_RXCLKSRC(3);
-		f->max_rate = 66000000;
+		/*
+		 * Use the SoC-specific SDR max rate if provided, otherwise
+		 * fall back to 66MHz (limit from IMX8MN datasheet §3.9.9).
+		 */
+		f->max_rate = f->devtype_data->max_sdr_rate ?
+			      f->devtype_data->max_sdr_rate : 66000000;
 	}
 	fspi_writel(f, reg, f->iobase + FSPI_MCR0);
 }
@@ -1457,10 +1533,11 @@ static const struct dev_pm_ops nxp_fspi_pm_ops = {
 static const struct of_device_id nxp_fspi_dt_ids[] = {
 	{ .compatible = "nxp,lx2160a-fspi", .data = (void *)&lx2160a_data, },
 	{ .compatible = "nxp,imx8mm-fspi", .data = (void *)&imx8mm_data, },
-	{ .compatible = "nxp,imx8mp-fspi", .data = (void *)&imx8mm_data, },
+	{ .compatible = "nxp,imx8mp-fspi", .data = (void *)&imx8mp_data, },
 	{ .compatible = "nxp,imx8qxp-fspi", .data = (void *)&imx8qxp_data, },
 	{ .compatible = "nxp,imx8dxl-fspi", .data = (void *)&imx8dxl_data, },
 	{ .compatible = "nxp,imx8ulp-fspi", .data = (void *)&imx8ulp_data, },
+	{ .compatible = "nxp,imx95-fspi",   .data = (void *)&imx95_data, },
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids);

-- 
2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL
  2026-07-28 10:18 [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi haibo.chen
  2026-07-28 10:18 ` [PATCH v2 1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs haibo.chen
@ 2026-07-28 10:18 ` haibo.chen
  2026-07-28 15:16   ` Frank Li
  2026-09-24 10:07   ` Michael Walle
  2026-07-28 10:18 ` [PATCH v2 3/3] spi: spi-nxp-fspi: propagate clock reconfig failures in nxp_fspi_select_mem() haibo.chen
  2026-07-30 12:14 ` [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi Mark Brown
  3 siblings, 2 replies; 10+ messages in thread
From: haibo.chen @ 2026-07-28 10:18 UTC (permalink / raw)
  To: Han Xu, Yogesh Gaur, Mark Brown; +Cc: linux-spi, imx, linux-kernel, Haibo Chen

From: Haibo Chen <haibo.chen@nxp.com>

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 <haibo.chen@nxp.com>
---
 drivers/spi/spi-nxp-fspi.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index 6de6d432cdcb2ee383a02d72f20000045903e176..a426b8d92193a4e303f411cd17c16cb31c3f3873 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);

-- 
2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 3/3] spi: spi-nxp-fspi: propagate clock reconfig failures in nxp_fspi_select_mem()
  2026-07-28 10:18 [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi haibo.chen
  2026-07-28 10:18 ` [PATCH v2 1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs haibo.chen
  2026-07-28 10:18 ` [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL haibo.chen
@ 2026-07-28 10:18 ` haibo.chen
  2026-07-30 12:14 ` [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi Mark Brown
  3 siblings, 0 replies; 10+ messages in thread
From: haibo.chen @ 2026-07-28 10:18 UTC (permalink / raw)
  To: Han Xu, Yogesh Gaur, Mark Brown; +Cc: linux-spi, imx, linux-kernel, Haibo Chen

From: Haibo Chen <haibo.chen@nxp.com>

nxp_fspi_select_mem() disables the FlexSPI clocks before calling
clk_set_rate() and re-enabling them. If clk_set_rate() or the clock
re-enable fails, the function returned early (as void) leaving both the
serial root clock and the register interface clock disabled.

As the function returned void, nxp_fspi_exec_op() had no way to know
about the failure and continued to access FlexSPI registers (LUT setup,
data transfer, AHB buffer invalidation). Accessing the controller
registers while its clock is gated off results in a synchronous external
abort.

Make nxp_fspi_select_mem() return an error code and have
nxp_fspi_exec_op() bail out on failure before any further register
access, including nxp_fspi_invalid().

Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
---
 drivers/spi/spi-nxp-fspi.c | 32 +++++++++++++++++++++++++-------
 1 file changed, 25 insertions(+), 7 deletions(-)

diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
index a426b8d92193a4e303f411cd17c16cb31c3f3873..67d991dd249d283e5a7b777c3ef4a70a9af3f065 100644
--- a/drivers/spi/spi-nxp-fspi.c
+++ b/drivers/spi/spi-nxp-fspi.c
@@ -859,8 +859,8 @@ static void nxp_fspi_dll_override(struct nxp_fspi *f)
  * Value for rest of the CS FLSHxxCR0 register would be zero.
  *
  */
-static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
-				const struct spi_mem_op *op)
+static int nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
+			       const struct spi_mem_op *op)
 {
 	/* flexspi only support one DTR mode: 8D-8D-8D */
 	bool op_is_dtr = op->cmd.dtr && op->addr.dtr && op->dummy.dtr && op->data.dtr;
@@ -881,7 +881,7 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
 	if ((f->selected == spi_get_chipselect(spi, 0)) &&
 	    (!!(f->flags & FSPI_DTR_MODE) == op_is_dtr) &&
 	    (f->pre_op_rate == op->max_freq))
-		return;
+		return 0;
 
 	/* Reset FLSHxxCR0 registers */
 	fspi_writel(f, 0, f->iobase + FSPI_FLSHA1CR0);
@@ -922,12 +922,19 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
 	nxp_fspi_clk_disable_unprep(f);
 
 	ret = clk_set_rate(f->clk, rate);
-	if (ret)
-		return;
+	if (ret) {
+		/*
+		 * clk_set_rate() failed with the clocks already disabled.
+		 * Re-enable them so the enable count matches what the caller's
+		 * pm_runtime_put() (runtime_suspend) will drop.
+		 */
+		nxp_fspi_clk_prep_enable(f);
+		return ret;
+	}
 
 	ret = nxp_fspi_clk_prep_enable(f);
 	if (ret)
-		return;
+		return ret;
 
 	/*
 	 * If clock rate > 100MHz, then switch from DLL override mode to
@@ -945,6 +952,8 @@ static void nxp_fspi_select_mem(struct nxp_fspi *f, struct spi_device *spi,
 	f->pre_op_rate = op->max_freq;
 
 	f->selected = spi_get_chipselect(spi, 0);
+
+	return 0;
 }
 
 static int nxp_fspi_read_ahb(struct nxp_fspi *f, const struct spi_mem_op *op)
@@ -1132,7 +1141,16 @@ static int nxp_fspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
 				   FSPI_STS0_ARB_IDLE, 1, POLL_TOUT, true);
 	WARN_ON(err);
 
-	nxp_fspi_select_mem(f, mem->spi, op);
+	err = nxp_fspi_select_mem(f, mem->spi, op);
+	if (err) {
+		/*
+		 * On failure the FlexSPI clock may be left disabled, so avoid
+		 * any further register access (which would trigger a synchronous
+		 * external abort) and bail out.
+		 */
+		pm_runtime_put_autosuspend(f->dev);
+		return err;
+	}
 
 	nxp_fspi_prepare_lut(f, op);
 	/*

-- 
2.34.1


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs
  2026-07-28 10:18 ` [PATCH v2 1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs haibo.chen
@ 2026-07-28 15:14   ` Frank Li
  0 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2026-07-28 15:14 UTC (permalink / raw)
  To: haibo.chen
  Cc: Han Xu, Yogesh Gaur, Mark Brown, linux-spi, imx, linux-kernel,
	Haibo Chen

On Tue, Jul 28, 2026 at 06:18:08PM +0800, haibo.chen@oss.nxp.com wrote:
> From: Haibo Chen <haibo.chen@nxp.com>
>
> The commit f43579ef3500 ("spi: spi-nxp-fspi: limit the clock rate for
> different sample clock source selection") introduced a global 166MHz
> cap for DTR mode (RXCLKSRC=3), based on the i.MX8MN datasheet timing
> specification (Section 3.9.9, page 65).
>
> After reviewing the FlexSPI timing parameters in the datasheets for all
> supported SoCs, the following corrections and additions are needed:
>
> 1. SDR mode (RXCLKSRC=0) limits vary per SoC:
>    - i.MX8MN/MM/MP/95: 66MHz  (IMX8MNCEC §3.9.9, IMX8MMCEC §3.9.10,
>                                 IMX8MPCEC, IMX95CEC Rev.8 §4.11.7)
>    - i.MX8QXP/QM/DXL/ULP: 60MHz (IMX8QXPCEC, IMX8QMCEC, IMX8DXLCEC,
>                                    IMX8ULPCEC §7.3.1 ND mode)
>    - LX2160A: 100MHz            (LX2160ACEC FlexSPI timing parameters)
>
> 2. DTR mode (RXCLKSRC=3) limits vary per SoC:
>    - i.MX8MN/MM/MP/ULP: 166MHz
>    - i.MX8QXP/QM/DXL: 200MHz   (same FlexSPI IP across this family)
>    - i.MX95: 200MHz             (IMX95CEC §4.11.7.3.2.3 Table 106)
>    - LX2160A: DTR disabled      (FSPI_QUIRK_DISABLE_DTR)
>
> Update related platform data with correct speed limation according
> to datasheet.
>
> Fixes: f43579ef3500 ("spi: spi-nxp-fspi: limit the clock rate for different sample clock source selection")
> Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/spi/spi-nxp-fspi.c | 83 ++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 80 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> index d94a2a7b98d44db217ba96a8ce7df23e37a08ba4..6de6d432cdcb2ee383a02d72f20000045903e176 100644
> --- a/drivers/spi/spi-nxp-fspi.c
> +++ b/drivers/spi/spi-nxp-fspi.c
> @@ -340,6 +340,18 @@ struct nxp_fspi_devtype_data {
>  	unsigned int quirks;
>  	unsigned int lut_num;
>  	bool little_endian;
> +	/*
> +	 * The max clock rate (Hz) that FlexSPI can output to the device
> +	 * in SDR mode (RXCLKSRC=0). Defaults to 66MHz if zero.
> +	 * Some SoCs (e.g. LX2160A) support up to 100MHz in SDR mode.
> +	 */
> +	unsigned long max_sdr_rate;
> +	/*
> +	 * The max clock rate (Hz) that FlexSPI can output to the device
> +	 * in DTR mode (RXCLKSRC=3). Defaults to 166MHz if zero.
> +	 * Some SoCs (e.g. i.MX95, i.MX8QM, i.MX8DXL) support up to 200MHz.
> +	 */
> +	unsigned long max_dtr_rate;
>  };
>
>  static struct nxp_fspi_devtype_data lx2160a_data = {
> @@ -349,6 +361,10 @@ static struct nxp_fspi_devtype_data lx2160a_data = {
>  	.quirks = FSPI_QUIRK_DISABLE_DTR,
>  	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
> +	/*
> +	 * LX2160ACEC: SDR RXCLKSRC=0 max 100MHz, DTR disabled via quirk.
> +	 */
> +	.max_sdr_rate = 100000000,
>  };
>
>  static struct nxp_fspi_devtype_data imx8mm_data = {
> @@ -358,6 +374,21 @@ static struct nxp_fspi_devtype_data imx8mm_data = {
>  	.quirks = 0,
>  	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
> +	/* IMX8MMCEC §3.9.10: SDR RXCLKSRC=0 max 66MHz, DDR RXCLKSRC=3 max 166MHz */
> +	.max_sdr_rate = 66000000,
> +	.max_dtr_rate = 166000000,
> +};
> +
> +static struct nxp_fspi_devtype_data imx8mp_data = {
> +	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
> +	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
> +	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
> +	.quirks = 0,
> +	.lut_num = 32,
> +	.little_endian = true,  /* little-endian    */
> +	/* IMX8MPCEC: SDR RXCLKSRC=0 max 66MHz, DDR RXCLKSRC=3 max 166MHz */
> +	.max_sdr_rate = 66000000,
> +	.max_dtr_rate = 166000000,
>  };
>
>  static struct nxp_fspi_devtype_data imx8qxp_data = {
> @@ -367,6 +398,12 @@ static struct nxp_fspi_devtype_data imx8qxp_data = {
>  	.quirks = 0,
>  	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
> +	/*
> +	 * IMX8QXPCEC: SDR RXCLKSRC=0 max 60MHz, DDR RXCLKSRC=3 max 200MHz.
> +	 * i.MX8QM and i.MX8DXL share the same FlexSPI IP and limits.
> +	 */
> +	.max_sdr_rate = 60000000,
> +	.max_dtr_rate = 200000000,
>  };
>
>  static struct nxp_fspi_devtype_data imx8dxl_data = {
> @@ -376,6 +413,12 @@ static struct nxp_fspi_devtype_data imx8dxl_data = {
>  	.quirks = FSPI_QUIRK_USE_IP_ONLY,
>  	.lut_num = 32,
>  	.little_endian = true,  /* little-endian    */
> +	/*
> +	 * IMX8DXLCEC (i.MX 8XLite): SDR RXCLKSRC=0 max 60MHz,
> +	 * DDR RXCLKSRC=3 max 200MHz.
> +	 */
> +	.max_sdr_rate = 60000000,
> +	.max_dtr_rate = 200000000,
>  };
>
>  static struct nxp_fspi_devtype_data imx8ulp_data = {
> @@ -385,6 +428,29 @@ static struct nxp_fspi_devtype_data imx8ulp_data = {
>  	.quirks = 0,
>  	.lut_num = 16,
>  	.little_endian = true,  /* little-endian    */
> +	/*
> +	 * IMX8ULPCEC §7.3.1, Normal Drive (ND, 1.0V) mode:
> +	 * SDR RXCLKSRC=0 max 60MHz, DDR RXCLKSRC=3 max 166MHz.
> +	 * Note: Overdrive (OD, 1.05V) allows up to 180MHz DTR
> +	 * but is not the default use case.
> +	 */
> +	.max_sdr_rate = 60000000,
> +	.max_dtr_rate = 166000000,
> +};
> +
> +static struct nxp_fspi_devtype_data imx95_data = {
> +	.rxfifo = SZ_512,       /* (64  * 64 bits)  */
> +	.txfifo = SZ_1K,        /* (128 * 64 bits)  */
> +	.ahb_buf_size = SZ_2K,  /* (256 * 64 bits)  */
> +	.quirks = 0,
> +	.lut_num = 32,
> +	.little_endian = true,  /* little-endian    */
> +	/*
> +	 * IMX95CEC Rev.8 §4.11.7: SDR RXCLKSRC=0 max 66MHz,
> +	 * DDR RXCLKSRC=3 max 200MHz (Nominal/Overdrive mode).
> +	 */
> +	.max_sdr_rate = 66000000,
> +	.max_dtr_rate = 200000000,
>  };
>
>  struct nxp_fspi {
> @@ -691,10 +757,20 @@ static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f,
>  	reg = fspi_readl(f, f->iobase + FSPI_MCR0);
>  	if (op_is_dtr) {
>  		reg |= FSPI_MCR0_RXCLKSRC(3);
> -		f->max_rate = 166000000;
> +		/*
> +		 * Use the SoC-specific DTR max rate if provided, otherwise
> +		 * fall back to 166MHz (limit from IMX8MN datasheet §3.9.9).
> +		 */
> +		f->max_rate = f->devtype_data->max_dtr_rate ?
> +			      f->devtype_data->max_dtr_rate : 166000000;
>  	} else {	/*select mode 0 */
>  		reg &= ~FSPI_MCR0_RXCLKSRC(3);
> -		f->max_rate = 66000000;
> +		/*
> +		 * Use the SoC-specific SDR max rate if provided, otherwise
> +		 * fall back to 66MHz (limit from IMX8MN datasheet §3.9.9).
> +		 */
> +		f->max_rate = f->devtype_data->max_sdr_rate ?
> +			      f->devtype_data->max_sdr_rate : 66000000;
>  	}
>  	fspi_writel(f, reg, f->iobase + FSPI_MCR0);
>  }
> @@ -1457,10 +1533,11 @@ static const struct dev_pm_ops nxp_fspi_pm_ops = {
>  static const struct of_device_id nxp_fspi_dt_ids[] = {
>  	{ .compatible = "nxp,lx2160a-fspi", .data = (void *)&lx2160a_data, },
>  	{ .compatible = "nxp,imx8mm-fspi", .data = (void *)&imx8mm_data, },
> -	{ .compatible = "nxp,imx8mp-fspi", .data = (void *)&imx8mm_data, },
> +	{ .compatible = "nxp,imx8mp-fspi", .data = (void *)&imx8mp_data, },
>  	{ .compatible = "nxp,imx8qxp-fspi", .data = (void *)&imx8qxp_data, },
>  	{ .compatible = "nxp,imx8dxl-fspi", .data = (void *)&imx8dxl_data, },
>  	{ .compatible = "nxp,imx8ulp-fspi", .data = (void *)&imx8ulp_data, },
> +	{ .compatible = "nxp,imx95-fspi",   .data = (void *)&imx95_data, },
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, nxp_fspi_dt_ids);
>
> --
> 2.34.1
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL
  2026-07-28 10:18 ` [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL haibo.chen
@ 2026-07-28 15:16   ` Frank Li
  2026-09-24 10:07   ` Michael Walle
  1 sibling, 0 replies; 10+ messages in thread
From: Frank Li @ 2026-07-28 15:16 UTC (permalink / raw)
  To: haibo.chen
  Cc: Han Xu, Yogesh Gaur, Mark Brown, linux-spi, imx, linux-kernel,
	Haibo Chen

On Tue, Jul 28, 2026 at 06:18:09PM +0800, haibo.chen@oss.nxp.com wrote:
> From: Haibo Chen <haibo.chen@nxp.com>
>
> 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 <haibo.chen@nxp.com>
> ---

Reviewed-by: Frank Li <Frank.Li@nxp.com>

>  drivers/spi/spi-nxp-fspi.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> index 6de6d432cdcb2ee383a02d72f20000045903e176..a426b8d92193a4e303f411cd17c16cb31c3f3873 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);
>
> --
> 2.34.1
>
>

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi
  2026-07-28 10:18 [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi haibo.chen
                   ` (2 preceding siblings ...)
  2026-07-28 10:18 ` [PATCH v2 3/3] spi: spi-nxp-fspi: propagate clock reconfig failures in nxp_fspi_select_mem() haibo.chen
@ 2026-07-30 12:14 ` Mark Brown
  3 siblings, 0 replies; 10+ messages in thread
From: Mark Brown @ 2026-07-30 12:14 UTC (permalink / raw)
  To: Han Xu, Yogesh Gaur, haibo.chen; +Cc: linux-spi, imx, linux-kernel, Haibo Chen

On Tue, 28 Jul 2026 18:18:07 +0800, haibo.chen@oss.nxp.com wrote:
> Few fix/improvement for spi-nxp-fspi
> 
> Patch 1 introduce per-SoC clock rate limits for both SDR and DTR modes
>         by adding max_sdr_rate and max_dtr_rate to nxp_fspi_devtype_data.
> Patch 2 enter stop mode before reconfiguring MCR0 and DLL to follow
> 	FlexSPI reference manual initialization sequence
> Patch 3 propagate clock reconfig failures in nxp_fspi_select_mem()
> 
> [...]

Applied to

   https://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi.git for-7.2

Thanks!

[1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs
      https://git.kernel.org/broonie/spi/c/9c19d60fea9f
[2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL
      https://git.kernel.org/broonie/spi/c/b4bde5cfff8e
[3/3] spi: spi-nxp-fspi: propagate clock reconfig failures in nxp_fspi_select_mem()
      https://git.kernel.org/broonie/spi/c/b5902b977979

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL
  2026-07-28 10:18 ` [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL haibo.chen
  2026-07-28 15:16   ` Frank Li
@ 2026-09-24 10:07   ` Michael Walle
  2026-09-24 10:25     ` Bough Chen (OSS)
  1 sibling, 1 reply; 10+ messages in thread
From: Michael Walle @ 2026-09-24 10:07 UTC (permalink / raw)
  To: haibo.chen, Han Xu, Yogesh Gaur, Mark Brown
  Cc: linux-spi, imx, linux-kernel, Haibo Chen

[-- Attachment #1: Type: text/plain, Size: 2833 bytes --]

On Tue Jul 28, 2026 at 12:18 PM CEST, haibo.chen wrote:
> From: Haibo Chen <haibo.chen@nxp.com>
>
> 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 <haibo.chen@nxp.com>

This will actually cause the following error on an i.MX 95 19x19 EVK
(imx95-19x19-evk.dts):

  nxp-fspi 425e0000.spi: DLL lock failed, please fix it!

Any ideas what causes this? I'm running the latest linux-next
kernel.

-michael

> ---
>  drivers/spi/spi-nxp-fspi.c | 14 ++++++++++++++
>  1 file changed, 14 insertions(+)
>
> diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> index 6de6d432cdcb2ee383a02d72f20000045903e176..a426b8d92193a4e303f411cd17c16cb31c3f3873 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);


[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 297 bytes --]

^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL
  2026-09-24 10:07   ` Michael Walle
@ 2026-09-24 10:25     ` Bough Chen (OSS)
  2026-09-28 10:42       ` Bough Chen (OSS)
  0 siblings, 1 reply; 10+ messages in thread
From: Bough Chen (OSS) @ 2026-09-24 10:25 UTC (permalink / raw)
  To: Michael Walle, Bough Chen (OSS), Han Xu, Yogesh Gaur, Mark Brown
  Cc: linux-spi, imx, linux-kernel, Bough Chen


NXP Confidential
> -----Original Message-----
> From: Michael Walle <michael@walle.cc>
> Sent: Thursday, September 24, 2026 6:08 PM
> To: Bough Chen (OSS) <haibo.chen@oss.nxp.com>; Han Xu
> <han.xu@nxp.com>; Yogesh Gaur <yogeshgaur.83@gmail.com>; Mark Brown
> <broonie@kernel.org>
> Cc: linux-spi@vger.kernel.org; imx@lists.linux.dev; linux-
> kernel@vger.kernel.org; Bough Chen <haibo.chen@nxp.com>
> Subject: Re: [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before
> reconfiguring MCR0 and DLL
>
> On Tue Jul 28, 2026 at 12:18 PM CEST, haibo.chen wrote:
> > From: Haibo Chen <haibo.chen@nxp.com>
> >
> > 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 <haibo.chen@nxp.com>
>
> This will actually cause the following error on an i.MX 95 19x19 EVK
> (imx95-19x19-evk.dts):
>
>   nxp-fspi 425e0000.spi: DLL lock failed, please fix it!
>
> Any ideas what causes this? I'm running the latest linux-next kernel.

Hi Michael, thanks for report this issue.

I can reproduce this issue on my side also, will look into it. I'll get back to you if I find anything.

Regards
Haibo Chen
>
> -michael
>
> > ---
> >  drivers/spi/spi-nxp-fspi.c | 14 ++++++++++++++
> >  1 file changed, 14 insertions(+)
> >
> > diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> > index
> >
> 6de6d432cdcb2ee383a02d72f20000045903e176..a426b8d92193a4e303f4
> 11cd17c1
> > 6cb31c3f3873 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);


^ permalink raw reply	[flat|nested] 10+ messages in thread

* RE: [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL
  2026-09-24 10:25     ` Bough Chen (OSS)
@ 2026-09-28 10:42       ` Bough Chen (OSS)
  0 siblings, 0 replies; 10+ messages in thread
From: Bough Chen (OSS) @ 2026-09-28 10:42 UTC (permalink / raw)
  To: Bough Chen (OSS), Michael Walle, Han Xu, Yogesh Gaur, Mark Brown
  Cc: linux-spi, imx, linux-kernel, Bough Chen

> -----Original Message-----
> From: Bough Chen (OSS) <haibo.chen@oss.nxp.com>
> Sent: Thursday, September 24, 2026 6:25 PM
> To: Michael Walle <michael@walle.cc>; Bough Chen (OSS)
> <haibo.chen@oss.nxp.com>; Han Xu <han.xu@nxp.com>; Yogesh Gaur
> <yogeshgaur.83@gmail.com>; Mark Brown <broonie@kernel.org>
> Cc: linux-spi@vger.kernel.org; imx@lists.linux.dev; linux-
> kernel@vger.kernel.org; Bough Chen <haibo.chen@nxp.com>
> Subject: RE: [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before
> reconfiguring MCR0 and DLL
> 
> 
> > -----Original Message-----
> > From: Michael Walle <michael@walle.cc>
> > Sent: Thursday, September 24, 2026 6:08 PM
> > To: Bough Chen (OSS) <haibo.chen@oss.nxp.com>; Han Xu
> > <han.xu@nxp.com>; Yogesh Gaur <yogeshgaur.83@gmail.com>; Mark
> Brown
> > <broonie@kernel.org>
> > Cc: linux-spi@vger.kernel.org; imx@lists.linux.dev; linux-
> > kernel@vger.kernel.org; Bough Chen <haibo.chen@nxp.com>
> > Subject: Re: [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before
> > reconfiguring MCR0 and DLL
> >
> > On Tue Jul 28, 2026 at 12:18 PM CEST, haibo.chen wrote:
> > > From: Haibo Chen <haibo.chen@nxp.com>
> > >
> > > 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 <haibo.chen@nxp.com>
> >
> > This will actually cause the following error on an i.MX 95 19x19 EVK
> > (imx95-19x19-evk.dts):
> >
> >   nxp-fspi 425e0000.spi: DLL lock failed, please fix it!
> >
> > Any ideas what causes this? I'm running the latest linux-next kernel.
> 
> Hi Michael, thanks for report this issue.
> 
> I can reproduce this issue on my side also, will look into it. I'll get back to you if
> I find anything.

Hi Michael,

I find the root cause. There are 2 issues here.

1, for the log:  nxp-fspi 425e0000.spi: DLL lock failed, please fix it!
    Yes, it is really involved by this patch, For DLL calibration, need to be done when module enable (MCR0[MDIS] = 0), otherwise, DLL will not lock.
    I will do more test on other platforms like imx8ulp/imx8m/imx91.  Will send one patch to fix it.

2. for the dump log: WARNING: drivers/spi/spi-nxp-fspi.c:1079 at nxp_fspi_exec_op+0xd88/0xe3c, CPU#1: kworker/u24:4/64
    After debug, I find even DLL do not lock in 8D-8D-8D mode, the first two command also done successfully, but the third command always trigger the WARN_ON(ret).
    Here is the command information when I dump the LUT.
[    1.887237] nxp-fspi 425e0000.spi: CMD[9f9f] lutval[0:879f879f 1:a700b310 2:00000000 3:00000000], size: 0x00000006
[    1.897633] nxp-fspi 425e0000.spi: CMD[505] lutval[0:87058705 1:a700b310 2:00000000 3:00000000], size: 0x00000002
[    1.907950] nxp-fspi 425e0000.spi: CMD[3535] lutval[0:87358735 1:a700b310 2:00000000 3:00000000], size: 0x00000002
   
CMD[9f9f] (RDID)、CMD[505] (RDSR) can be done normally,only CMD[3535] (RDSR2)  trigger the timeout.
the spi-nor on imx95-19x19-evk board is mt35xu512aba, and it do not support RDSR2. I add the following change then issue gone:

diff --git a/drivers/mtd/spi-nor/micron-st.c b/drivers/mtd/spi-nor/micron-st.c
index f97f2dead8c2..35bf386bb66a 100644
--- a/drivers/mtd/spi-nor/micron-st.c
+++ b/drivers/mtd/spi-nor/micron-st.c
@@ -180,7 +180,8 @@ static int mt35xu512aba_post_sfdp_fixup(struct spi_nor *nor)
        nor->params->cmd_ext_type = SPI_NOR_EXT_REPEAT;
        nor->params->rdsr_dummy = 8;
        nor->params->rdsr_addr_nbytes = 0;
-
+
+       nor->params->opcodes.read_sr2 = 0;
        /*
         * The BFPT quad enable field is set to a reserved value so the quad
         * enable function is ignored by spi_nor_parse_bfpt(). Make sure we

This is involved by commit 63489002d397 ("mtd: spi-nor: Refactor Read Status/Write Status support"), seems not only micron-st is impacted, I will find a correct method and send patch to fix it.

Regards
Haibo Chen


> 
> Regards
> Haibo Chen
> >
> > -michael
> >
> > > ---
> > >  drivers/spi/spi-nxp-fspi.c | 14 ++++++++++++++
> > >  1 file changed, 14 insertions(+)
> > >
> > > diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> > > index
> > >
> >
> 6de6d432cdcb2ee383a02d72f20000045903e176..a426b8d92193a4e303f4
> > 11cd17c1
> > > 6cb31c3f3873 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);
> 


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2026-09-28 10:42 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-28 10:18 [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi haibo.chen
2026-07-28 10:18 ` [PATCH v2 1/3] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs haibo.chen
2026-07-28 15:14   ` Frank Li
2026-07-28 10:18 ` [PATCH v2 2/3] spi: spi-nxp-fspi: enter stop mode before reconfiguring MCR0 and DLL haibo.chen
2026-07-28 15:16   ` Frank Li
2026-09-24 10:07   ` Michael Walle
2026-09-24 10:25     ` Bough Chen (OSS)
2026-09-28 10:42       ` Bough Chen (OSS)
2026-07-28 10:18 ` [PATCH v2 3/3] spi: spi-nxp-fspi: propagate clock reconfig failures in nxp_fspi_select_mem() haibo.chen
2026-07-30 12:14 ` [PATCH v2 0/3] Few fix/improvement for spi-nxp-fspi Mark Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®