Patch "spi: fsl-dspi: avoid SCK glitches with continuous transfers" has been added to the 5.4-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    spi: fsl-dspi: avoid SCK glitches with continuous transfers

to the 5.4-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     spi-fsl-dspi-avoid-sck-glitches-with-continuous-tran.patch
and it can be found in the queue-5.4 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 48d7bea6c91cebde42242fa22b333a899d8b6e02
Author: Vladimir Oltean <vladimir.oltean@xxxxxxx>
Date:   Tue May 30 01:34:02 2023 +0300

    spi: fsl-dspi: avoid SCK glitches with continuous transfers
    
    [ Upstream commit c5c31fb71f16ba75bad4ade208abbae225305b65 ]
    
    The DSPI controller has configurable timing for
    
    (a) tCSC: the interval between the assertion of the chip select and the
        first clock edge
    
    (b) tASC: the interval between the last clock edge and the deassertion
        of the chip select
    
    What is a bit surprising, but is documented in the figure "Example of
    continuous transfer (CPHA=1, CONT=1)" in the datasheet, is that when the
    chip select stays asserted between multiple TX FIFO writes, the tCSC and
    tASC times still apply. With CONT=1, chip select remains asserted, but
    SCK takes a break and goes to the idle state for tASC + tCSC ns.
    
    In other words, the default values (of 0 and 0 ns) result in SCK
    glitches where the SCK transition to the idle state, as well as the SCK
    transition from the idle state, will have no delay in between, and it
    may appear that a SCK cycle has simply gone missing. The resulting
    timing violation might cause data corruption in many peripherals, as
    their chip select is asserted.
    
    The driver has device tree bindings for tCSC ("fsl,spi-cs-sck-delay")
    and tASC ("fsl,spi-sck-cs-delay"), but these are only specified to apply
    when the chip select toggles in the first place, and this timing
    characteristic depends on each peripheral. Many peripherals do not have
    explicit timing requirements, so many device trees do not have these
    properties present at all.
    
    Nonetheless, the lack of SCK glitches is a common sense requirement, and
    since the SCK stays in the idle state during transfers for tCSC+tASC ns,
    and that in itself should look like half a cycle, then let's ensure that
    tCSC and tASC are at least a quarter of a SCK period, such that their
    sum is at least half of one.
    
    Fixes: 95bf15f38641 ("spi: fsl-dspi: Add ~50ns delay between cs and sck")
    Reported-by: Lisa Chen (陈敏捷) <minjie.chen@xxxxxxxxxxxx>
    Debugged-by: Lisa Chen (陈敏捷) <minjie.chen@xxxxxxxxxxxx>
    Tested-by: Lisa Chen (陈敏捷) <minjie.chen@xxxxxxxxxxxx>
    Signed-off-by: Vladimir Oltean <vladimir.oltean@xxxxxxx>
    Link: https://lore.kernel.org/r/20230529223402.1199503-1-vladimir.oltean@xxxxxxx
    Signed-off-by: Mark Brown <broonie@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 51e17f0828646..351b2989db071 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -816,7 +816,9 @@ static int dspi_transfer_one_message(struct spi_controller *ctlr,
 static int dspi_setup(struct spi_device *spi)
 {
 	struct fsl_dspi *dspi = spi_controller_get_devdata(spi->controller);
+	u32 period_ns = DIV_ROUND_UP(NSEC_PER_SEC, spi->max_speed_hz);
 	unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0;
+	u32 quarter_period_ns = DIV_ROUND_UP(period_ns, 4);
 	u32 cs_sck_delay = 0, sck_cs_delay = 0;
 	struct fsl_dspi_platform_data *pdata;
 	unsigned char pasc = 0, asc = 0;
@@ -844,6 +846,19 @@ static int dspi_setup(struct spi_device *spi)
 		sck_cs_delay = pdata->sck_cs_delay;
 	}
 
+	/* Since tCSC and tASC apply to continuous transfers too, avoid SCK
+	 * glitches of half a cycle by never allowing tCSC + tASC to go below
+	 * half a SCK period.
+	 */
+	if (cs_sck_delay < quarter_period_ns)
+		cs_sck_delay = quarter_period_ns;
+	if (sck_cs_delay < quarter_period_ns)
+		sck_cs_delay = quarter_period_ns;
+
+	dev_dbg(&spi->dev,
+		"DSPI controller timing params: CS-to-SCK delay %u ns, SCK-to-CS delay %u ns\n",
+		cs_sck_delay, sck_cs_delay);
+
 	clkrate = clk_get_rate(dspi->clk);
 	hz_to_spi_baud(&pbr, &br, spi->max_speed_hz, clkrate);
 



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux