drivers: dma: siwx91x: Fix DMA_ADDR_ADJ_NO_CHANGE w/ memory source
GPDMA does not support DMA_ADDR_ADJ_NO_CHANGE with a memory buffer. This
feature is required for the SPI driver. Hopefully, SPI driver is the only
user of this feature.
Therefore, this commit introduces a hack for SPI. When the user request an
Rx transaction, rather than copying content of mosi_overrun parameter, it
configures the DMA to fill the destination memory (with either 0s or 1s).
Obviously, this only works if mosi_overrun is 0x00 or 0xFF. Hopefully, none
will need any other value.
Signed-off-by: Jérôme Pouiller <jerome.pouiller@silabs.com>
diff --git a/drivers/dma/dma_silabs_siwx91x_gpdma.c b/drivers/dma/dma_silabs_siwx91x_gpdma.c
index b52ac29..177c806 100644
--- a/drivers/dma/dma_silabs_siwx91x_gpdma.c
+++ b/drivers/dma/dma_silabs_siwx91x_gpdma.c
@@ -183,6 +183,22 @@
}
if (block->source_addr_adj == DMA_ADDR_ADJ_NO_CHANGE) {
desc->chnlCtrlConfig.srcFifoMode = 1;
+ /* HACK: GPDMA does not support DMA_ADDR_ADJ_NO_CHANGE with a memory buffer.
+ * So, instead of transferring the real data, we fill the peripheral with 0s
+ * or 1s. It should be sufficient for most of the SPI usages. We hope the
+ * users won't need any values other than 0x00 of 0xFF.
+ */
+ if (config->channel_direction == MEMORY_TO_PERIPHERAL) {
+ desc->miscChnlCtrlConfig.memoryFillEn = 1;
+ if (*(uint8_t *)block->source_address == 0xFF) {
+ desc->miscChnlCtrlConfig.memoryOneFill = 1;
+ } else if (*(uint8_t *)block->source_address == 0x00) {
+ desc->miscChnlCtrlConfig.memoryOneFill = 0;
+ } else {
+ LOG_ERR("Only 0xFF and 0x00 are supported as input");
+ goto free_desc;
+ }
+ }
}