]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
spi: spi-nxp-fspi: limit the clock rate for different sample clock source selection
authorHaibo Chen <haibo.chen@nxp.com>
Mon, 22 Sep 2025 08:47:15 +0000 (16:47 +0800)
committerMark Brown <broonie@kernel.org>
Mon, 13 Oct 2025 12:32:48 +0000 (13:32 +0100)
For different sample clock source selection, the max frequency
flexspi supported are different. For mode 0, max frequency is 66MHz.
For mode 3, the max frequency is 166MHz.

Refer to 3.9.9 FlexSPI timing parameters on page 65.
https://www.nxp.com/docs/en/data-sheet/IMX8MNCEC.pdf

Though flexspi maybe still work under higher frequency, but can't
guarantee the stability. IC suggest to add this limitation on all
SoCs which contain flexspi.

Fixes: c07f27032317 ("spi: spi-nxp-fspi: add the support for sample data from DQS pad")
Signed-off-by: Haibo Chen <haibo.chen@nxp.com>
Link: https://patch.msgid.link/20250922-fspi-fix-v1-3-ff4315359d31@nxp.com
Signed-off-by: Mark Brown <broonie@kernel.org>
drivers/spi/spi-nxp-fspi.c

index 96b3654b45abcaf53266ce9acac8d6578a19458a..b6c79e50d842fa2d0aa9cbd16f9e5f28405ef710 100644 (file)
@@ -406,6 +406,8 @@ struct nxp_fspi {
        int flags;
        /* save the previous operation clock rate */
        unsigned long pre_op_rate;
+       /* the max clock rate fspi output to device */
+       unsigned long max_rate;
 };
 
 static inline int needs_ip_only(struct nxp_fspi *f)
@@ -687,10 +689,13 @@ static void nxp_fspi_select_rx_sample_clk_source(struct nxp_fspi *f,
         * change the mode back to mode 0.
         */
        reg = fspi_readl(f, f->iobase + FSPI_MCR0);
-       if (op_is_dtr)
+       if (op_is_dtr) {
                reg |= FSPI_MCR0_RXCLKSRC(3);
-       else    /*select mode 0 */
+               f->max_rate = 166000000;
+       } else {        /*select mode 0 */
                reg &= ~FSPI_MCR0_RXCLKSRC(3);
+               f->max_rate = 66000000;
+       }
        fspi_writel(f, reg, f->iobase + FSPI_MCR0);
 }
 
@@ -816,6 +821,7 @@ 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));
 
        nxp_fspi_select_rx_sample_clk_source(f, op_is_dtr);
+       rate = min(f->max_rate, op->max_freq);
 
        if (op_is_dtr) {
                f->flags |= FSPI_DTR_MODE;