From b48f764a921f98ff72e84bda36c5184cb5e88188 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 7 Jul 2026 10:13:49 +0200 Subject: [PATCH 1/3] drivers: spi: siwx91x: CS released too early MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When the SPI hardware block is use to send data (without receiving any data), the DMA callback is called when the data are transmitted to the SPI controller, but before the data are actually sent over the wire. Then, the chip-select signal could be released while the Tx was still in progress. Upstream-status: pr Signed-off-by: Jérôme Pouiller (cherry picked from commit 79d52762d1ad9b45616b543d0fcc62ffd2da8503) --- drivers/spi/spi_silabs_siwx91x_gspi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 0bf332a58b00..4f5fde62990d 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -186,6 +186,7 @@ static void gspi_siwx91x_dma_callback(const struct device *dev, void *user_data, int status) { const struct device *spi_dev = (const struct device *)user_data; + const struct gspi_siwx91x_config *cfg = spi_dev->config; struct gspi_siwx91x_data *data = spi_dev->data; struct spi_context *instance_ctx = &data->ctx; @@ -200,6 +201,9 @@ static void gspi_siwx91x_dma_callback(const struct device *dev, void *user_data, dma_stop(data->dma_rx.dma_dev, data->dma_rx.chan_nb); } + while (cfg->reg->GSPI_STATUS_b.GSPI_BUSY) { + /* empty */ + } spi_context_cs_control(instance_ctx, false); spi_context_complete(instance_ctx, spi_dev, status); pm_device_runtime_put_async(spi_dev, K_NO_WAIT); From abc215372f46010c0117c04b6b0973060b8bcfbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 7 Jul 2026 10:16:58 +0200 Subject: [PATCH 2/3] drivers: spi: siwx91x: Fix busy loop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The siwx91x SPI driver required to wait for a very small amouth of time (100ns to 50µs). When CONFIG_PM is enabled, the granularity of k_busy_wait() is not sufficient (~32µs). So, the driver implement a raw busy loop. This busy loop depends on the frequency of the CPU. This was wrongly retrieved from CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC. DT_PROP(DT_NODELABEL(cpu0), clock_frequency) is more accurate. Upstream-status: pr Signed-off-by: Jérôme Pouiller (cherry picked from commit 8db4d921a9660faa3cb5cf5c578284d35a3c3705) --- drivers/spi/spi_silabs_siwx91x_gspi.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi_silabs_siwx91x_gspi.c b/drivers/spi/spi_silabs_siwx91x_gspi.c index 4f5fde62990d..40f90adfa881 100644 --- a/drivers/spi/spi_silabs_siwx91x_gspi.c +++ b/drivers/spi/spi_silabs_siwx91x_gspi.c @@ -397,13 +397,16 @@ static int gspi_siwx91x_burst_size(struct spi_context *ctx) static void gspi_siwx91x_gspi_fifo_reset_sync(uint32_t frequency) { - int loops = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / frequency; + int loops = DT_PROP(DT_NODELABEL(cpu0), clock_frequency) / frequency; - /* GSPI FIFO reset requires the RESET bits to be held high - * for at least one GSPI bus clock cycle. - * Since there is no explicit hardware status indicating - * completion of the FIFO reset, insert a short, frequency- - * dependent delay to guarantee the minimum reset pulse width. + /* GSPI FIFO reset requires the RESET bits to be held high for at least + * one GSPI bus clock cycle. + * Since there is no explicit hardware status indicating completion of + * the FIFO reset, insert a short, frequency-dependent delay to + * guarantee the minimum reset pulse width. + */ + /* FIXME: The granularity of k_busy_wait() is only 32µs when + * CONFIG_PM=y. */ while (loops-- > 0) { arch_nop(); From 8efef79193611d7d9587212eb277e72635910b0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Tue, 7 Jul 2026 11:04:54 +0200 Subject: [PATCH 3/3] drivers: spi: siwx91x: Fix tests with PM MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With CONFIG_PM=y, the duration of the SPI transfer is slightly longer. Upstream-status: pr Signed-off-by: Jérôme Pouiller (cherry picked from commit 7b1c961caa00b63944b3c1e5e1d33bea037da916) --- tests/drivers/spi/spi_loopback/boards/siwx917_rb4338a.conf | 2 +- tests/drivers/spi/spi_loopback/boards/siwx917_rb4342a.conf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/drivers/spi/spi_loopback/boards/siwx917_rb4338a.conf b/tests/drivers/spi/spi_loopback/boards/siwx917_rb4338a.conf index 5baf9d246f6e..418f8f5ca2d5 100644 --- a/tests/drivers/spi/spi_loopback/boards/siwx917_rb4338a.conf +++ b/tests/drivers/spi/spi_loopback/boards/siwx917_rb4338a.conf @@ -1,2 +1,2 @@ CONFIG_DMA=y -CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=14 +CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=15 diff --git a/tests/drivers/spi/spi_loopback/boards/siwx917_rb4342a.conf b/tests/drivers/spi/spi_loopback/boards/siwx917_rb4342a.conf index 5baf9d246f6e..418f8f5ca2d5 100644 --- a/tests/drivers/spi/spi_loopback/boards/siwx917_rb4342a.conf +++ b/tests/drivers/spi/spi_loopback/boards/siwx917_rb4342a.conf @@ -1,2 +1,2 @@ CONFIG_DMA=y -CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=14 +CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=15