@@ -27,6 +27,7 @@ LOG_MODULE_REGISTER(spi_siwx91x_gspi, CONFIG_SPI_LOG_LEVEL);
2727#define GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK 110000000
2828#define GSPI_MAX_BAUDRATE_FOR_POS_EDGE_SAMPLE 40000000
2929#define GSPI_DMA_MAX_DESCRIPTOR_TRANSFER_SIZE 4096
30+ #define SPI_HIGH_BURST_FREQ_THRESHOLD_HZ 10000000
3031
3132/* Warning for unsupported configurations */
3233#if defined(CONFIG_SPI_ASYNC ) && !defined(CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA )
@@ -247,16 +248,16 @@ static void gspi_siwx91x_dma_tx_callback(const struct device *dev, void *user_da
247248
248249static int gspi_siwx91x_dma_config (const struct device * dev ,
249250 struct gspi_siwx91x_dma_channel * channel , uint32_t block_count ,
250- bool is_tx , uint8_t dfs )
251+ bool is_tx , uint8_t dfs , uint8_t burst_size )
251252{
252253 struct dma_config cfg = {
253254 .channel_direction = is_tx ? MEMORY_TO_PERIPHERAL : PERIPHERAL_TO_MEMORY ,
254255 .channel_priority = 1 ,
255256 .complete_callback_en = 0 ,
256257 .source_data_size = dfs ,
257258 .dest_data_size = dfs ,
258- .source_burst_length = 1 ,
259- .dest_burst_length = 1 ,
259+ .source_burst_length = burst_size ,
260+ .dest_burst_length = burst_size ,
260261 .block_count = block_count ,
261262 .head_block = channel -> dma_descriptors ,
262263 .dma_slot = channel -> dma_slot ,
@@ -374,7 +375,8 @@ static void gspi_siwx91x_reset_desc(struct gspi_siwx91x_dma_channel *channel)
374375static int gspi_siwx91x_prepare_dma_channel (const struct device * spi_dev ,
375376 const struct spi_buf * buffer , size_t buffer_count ,
376377 struct gspi_siwx91x_dma_channel * channel ,
377- size_t padded_transaction_size , bool is_tx )
378+ size_t padded_transaction_size , bool is_tx ,
379+ uint8_t burst_size )
378380{
379381 const struct gspi_siwx91x_config * cfg = spi_dev -> config ;
380382 struct gspi_siwx91x_data * data = spi_dev -> data ;
@@ -391,12 +393,13 @@ static int gspi_siwx91x_prepare_dma_channel(const struct device *spi_dev,
391393 }
392394
393395 ret = gspi_siwx91x_dma_config (spi_dev , channel ,
394- ARRAY_INDEX (channel -> dma_descriptors , desc ) + 1 , is_tx , dfs );
396+ ARRAY_INDEX (channel -> dma_descriptors , desc ) + 1 , is_tx , dfs ,
397+ burst_size );
395398 return ret ;
396399}
397400
398401static int gspi_siwx91x_prepare_dma_transaction (const struct device * dev ,
399- size_t padded_transaction_size )
402+ size_t padded_transaction_size , uint8_t burst_size )
400403{
401404 int ret ;
402405 struct gspi_siwx91x_data * data = dev -> data ;
@@ -406,13 +409,15 @@ static int gspi_siwx91x_prepare_dma_transaction(const struct device *dev,
406409 }
407410
408411 ret = gspi_siwx91x_prepare_dma_channel (dev , data -> ctx .current_tx , data -> ctx .tx_count ,
409- & data -> dma_tx , padded_transaction_size , true);
412+ & data -> dma_tx , padded_transaction_size , true,
413+ burst_size );
410414 if (ret ) {
411415 return ret ;
412416 }
413417
414418 ret = gspi_siwx91x_prepare_dma_channel (dev , data -> ctx .current_rx , data -> ctx .rx_count ,
415- & data -> dma_rx , padded_transaction_size , false);
419+ & data -> dma_rx , padded_transaction_size , false,
420+ burst_size );
416421
417422 return ret ;
418423}
@@ -425,6 +430,34 @@ static size_t gspi_siwx91x_longest_transfer_size(struct spi_context *instance_ct
425430 return MAX (tx_transfer_size , rx_transfer_size );
426431}
427432
433+ static int gspi_siwx91x_burst_size_buf (const struct spi_buf * dma_spi_buf )
434+ {
435+ int burst_len = 4 ;
436+
437+ if (!dma_spi_buf -> buf || !dma_spi_buf -> len ) {
438+ return burst_len ;
439+ }
440+
441+ burst_len = MIN (burst_len , BIT (find_lsb_set ((uint32_t )dma_spi_buf -> buf ) - 1 ));
442+ burst_len = MIN (burst_len , BIT (find_lsb_set (dma_spi_buf -> len ) - 1 ));
443+
444+ return burst_len ;
445+ }
446+
447+ static int gspi_siwx91x_burst_size (struct spi_context * ctx )
448+ {
449+ int burst_len = 4 ;
450+
451+ for (int i = 0 ; i < ctx -> tx_count ; i ++ ) {
452+ burst_len = MIN (burst_len , gspi_siwx91x_burst_size_buf (ctx -> current_tx + i ));
453+ }
454+
455+ for (int i = 0 ; i < ctx -> rx_count ; i ++ ) {
456+ burst_len = MIN (burst_len , gspi_siwx91x_burst_size_buf (ctx -> current_rx + i ));
457+ }
458+
459+ return burst_len ;
460+ }
428461#endif /* CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA */
429462
430463static int gspi_siwx91x_transceive_dma (const struct device * dev , const struct spi_config * config )
@@ -435,17 +468,42 @@ static int gspi_siwx91x_transceive_dma(const struct device *dev, const struct sp
435468 const struct device * dma_dev = data -> dma_rx .dma_dev ;
436469 struct spi_context * ctx = & data -> ctx ;
437470 size_t padded_transaction_size = gspi_siwx91x_longest_transfer_size (ctx );
471+ uint8_t burst_size = 1 ;
438472 int ret = 0 ;
439473
440474 if (padded_transaction_size == 0 ) {
441475 return - EINVAL ;
442476 }
443477
478+ if (config -> frequency >= SPI_HIGH_BURST_FREQ_THRESHOLD_HZ &&
479+ data -> dma_rx .dma_slot != 0xFF && data -> dma_tx .dma_slot != 0xFF ) {
480+ /* NOTE: This condition ensures that high burst rates are only used with GPDMA.
481+ *
482+ * GPDMA (General-Purpose DMA) supports higher burst rates and operates at higher
483+ * frequencies, unlike UDMA, which does not handle such speeds reliably.
484+ * Therefore, the DMA slots are validated to ensure that the active DMA channels
485+ * belong to GPDMA before enabling higher burst rates.
486+ *
487+ * Currently, DMA flow control (DMA_FLOW_CTRL) is not functioning correctly for
488+ * memory-to-peripheral and peripheral-to-memory transfers. As a result, at lower
489+ * SPI clock frequencies, GPDMA may read/write FIFOs at a much higher rate than the
490+ * SPI peripheral, causing synchronization issues. However, at higher SPI clock
491+ * frequencies (≥ 10 MHz), this timing mismatch is negligible, and higher burst
492+ * rates operate as expected.
493+ *
494+ * In summary, high burst rates are safely enabled only for SPI transfers running
495+ * at or above 10 MHz when using GPDMA.
496+ */
497+ burst_size = gspi_siwx91x_burst_size (ctx );
498+ }
499+
444500 cfg -> reg -> GSPI_FIFO_THRLD_b .RFIFO_RESET = 1 ;
445501 cfg -> reg -> GSPI_FIFO_THRLD_b .WFIFO_RESET = 1 ;
446502 cfg -> reg -> GSPI_FIFO_THRLD = 0 ;
503+ cfg -> reg -> GSPI_FIFO_THRLD_b .FIFO_AEMPTY_THRLD = burst_size - 1 ;
504+ cfg -> reg -> GSPI_FIFO_THRLD_b .FIFO_AFULL_THRLD = burst_size - 1 ;
447505
448- ret = gspi_siwx91x_prepare_dma_transaction (dev , padded_transaction_size );
506+ ret = gspi_siwx91x_prepare_dma_transaction (dev , padded_transaction_size , burst_size );
449507 if (ret ) {
450508 return ret ;
451509 }
0 commit comments