RE: [PATCH] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits for all supported SoCs

Bough Chen <[email protected]>
Newsgroups dev.linux.lists.imx,org.kernel.vger.linux-kernel,org.kernel.vger.linux-spi
Message-ID <DU2PR04MB8677BB5F3E541B0EB3F8D70E90CB2@DU2PR04MB8677.eurprd04.prod.outlook.com>
> -----Original Message-----
> From: Frank Li (OSS) <[email protected]>
> Sent: 2026年7月27日 23:00
> To: Bough Chen (OSS) <[email protected]>
> Cc: Han Xu <[email protected]>; Yogesh Gaur <[email protected]>;
> Mark Brown <[email protected]>; [email protected];
> [email protected]; [email protected]; Bough Chen
> <[email protected]>
> Subject: Re: [PATCH] spi: spi-nxp-fspi: add per-SoC SDR/DTR clock rate limits
> for all supported SoCs
> 
> On Mon, Jul 27, 2026 at 05:08:47PM +0800, [email protected]
> wrote:
> > From: Haibo Chen <[email protected]>
> >
> > 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)
> >
> > - Add max_sdr_rate and max_dtr_rate field to nxp_fspi_devtype_data
> > - Use per-SoC max_sdr_rate in nxp_fspi_select_rx_sample_clk_source(),
> >   falling back to 66MHz default when zero (preserves existing behavior
> >   for any future SoC entries that omit the field)
> > - Use per-SoC max_ddr_rate in nxp_fspi_select_rx_sample_clk_source(),
> >   falling back to 166MHz default when zero (preserves existing behavior
> >   for any future SoC entries that omit the field)
> > - Add dedicated imx8mp_data (previously aliased to imx8mm_data) with
> >   explicit frequency limits
> > - Update imx8qxp_data, imx8dxl_data with correct 60/200MHz limits
> > - Update imx8ulp_data with ND (Normal Drive, 1.0V) mode limits:
> > 60/166MHz
> > - Update lx2160a_data with correct SDR 100MHz limit
> > - Update imx95_data with correct 66/200MHz limits
> 
> Update related platform data with correct speed limation according to
> datasheet.
> 
> You already list frequency at above 1/2, needn't duplicate these informaiton
> again.
> 
> > Note: i.MX8ULP limits are specified for Normal Drive (ND, 1.0V) mode
> > as this is the standard operating condition. Overdrive (OD, 1.05V)
> > allows up to 180MHz DTR but is not the default use case.
> 
> Move this to comments.

Thanks for the suggestions, will update in V2.

Regards
Haibo Chen
> 
> Frank
> >
> > Fixes: f43579ef3500 ("spi: spi-nxp-fspi: limit the clock rate for
> > different sample clock source selection")
> > Signed-off-by: Haibo Chen <[email protected]>
> > ---
> >  drivers/spi/spi-nxp-fspi.c | 81
> > ++++++++++++++++++++++++++++++++++++++++++++--
> >  1 file changed, 78 insertions(+), 3 deletions(-)
> >
> > diff --git a/drivers/spi/spi-nxp-fspi.c b/drivers/spi/spi-nxp-fspi.c
> > index
> >
> d94a2a7b98d44db217ba96a8ce7df23e37a08ba4..1159f5fc8a3a69eb464f32
> fd92e2
> > 83e84ebd67ab 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,27 @@ 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.
> > +	 */
> > +	.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 +755,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 +1531,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);
> >
> > ---
> > base-commit: c5e32e86ca02b003f86e095d379b38148999293d
> > change-id: 20260727-fspi-clock-adcae0c35283
> >
> > Best regards,
> > --
> > Haibo Chen <[email protected]>
> >
> >
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.