drivers: dma: add linked list in dmau5 driver

- Init linked list node and structure
- configure source and destination address
- Setting gpdma request mode
- Configure linked list node and structure for
continous transfer, enable half transfert irq.

Signed-off-by: Fabrice DJIATSA <fabrice.djiatsa-ext@st.com>
co-authored-by: Lubos Koudelka <lubos.koudelka@st.com>
This commit is contained in:
Fabrice DJIATSA 2025-01-15 13:44:48 +01:00 committed by Benjamin Cabé
parent ed92eeb3c8
commit 7b379f47fa

View file

@ -353,6 +353,13 @@ static int dma_stm32_configure(const struct device *dev,
LL_DMA_InitTypeDef DMA_InitStruct; LL_DMA_InitTypeDef DMA_InitStruct;
int ret; int ret;
/* Linked list Node and structure initialization */
static LL_DMA_LinkNodeTypeDef Node_GPDMA_Channel;
LL_DMA_InitLinkedListTypeDef DMA_InitLinkedListStruct;
LL_DMA_InitNodeTypeDef NodeConfig;
LL_DMA_ListStructInit(&DMA_InitLinkedListStruct);
LL_DMA_NodeStructInit(&NodeConfig);
LL_DMA_StructInit(&DMA_InitStruct); LL_DMA_StructInit(&DMA_InitStruct);
/* Give channel from index 0 */ /* Give channel from index 0 */
@ -408,16 +415,6 @@ static int dma_stm32_configure(const struct device *dev,
return -EINVAL; return -EINVAL;
} }
/* Continuous transfers are supported by hardware but not implemented
* by this driver
*/
if (config->head_block->source_reload_en ||
config->head_block->dest_reload_en) {
LOG_ERR("source_reload_en and dest_reload_en not "
"implemented.");
return -EINVAL;
}
stream->busy = true; stream->busy = true;
stream->dma_callback = config->dma_callback; stream->dma_callback = config->dma_callback;
stream->direction = config->channel_direction; stream->direction = config->channel_direction;
@ -436,8 +433,9 @@ static int dma_stm32_configure(const struct device *dev,
DMA_InitStruct.SrcAddress = config->head_block->source_address; DMA_InitStruct.SrcAddress = config->head_block->source_address;
DMA_InitStruct.DestAddress = config->head_block->dest_address; DMA_InitStruct.DestAddress = config->head_block->dest_address;
DMA_InitStruct.BlkHWRequest = LL_DMA_HWREQUEST_SINGLEBURST; NodeConfig.SrcAddress = config->head_block->source_address;
DMA_InitStruct.DataAlignment = LL_DMA_DATA_ALIGN_ZEROPADD; NodeConfig.DestAddress = config->head_block->dest_address;
NodeConfig.BlkDataLength = config->head_block->block_size;
ret = dma_stm32_get_priority(config->channel_priority, ret = dma_stm32_get_priority(config->channel_priority,
&DMA_InitStruct.Priority); &DMA_InitStruct.Priority);
@ -502,18 +500,40 @@ static int dma_stm32_configure(const struct device *dev,
/* The request ID is stored in the dma_slot */ /* The request ID is stored in the dma_slot */
DMA_InitStruct.Request = config->dma_slot; DMA_InitStruct.Request = config->dma_slot;
if (config->head_block->source_reload_en == 0) {
/* Initialize the DMA structure in non-cyclic mode only */
LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct); LL_DMA_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitStruct);
} else {/* cyclic mode */
/* Setting GPDMA request */
NodeConfig.DestDataWidth = DMA_InitStruct.DestDataWidth;
NodeConfig.SrcDataWidth = DMA_InitStruct.SrcDataWidth;
NodeConfig.DestIncMode = DMA_InitStruct.DestIncMode;
NodeConfig.SrcIncMode = DMA_InitStruct.SrcIncMode;
NodeConfig.Direction = DMA_InitStruct.Direction;
NodeConfig.Request = DMA_InitStruct.Request;
/* Continuous transfers with Linked List */
stream->cyclic = true;
LL_DMA_List_Init(dma, dma_stm32_id_to_stream(id), &DMA_InitLinkedListStruct);
LL_DMA_CreateLinkNode(&NodeConfig, &Node_GPDMA_Channel);
LL_DMA_ConnectLinkNode(&Node_GPDMA_Channel, LL_DMA_CLLR_OFFSET5,
&Node_GPDMA_Channel, LL_DMA_CLLR_OFFSET5);
LL_DMA_SetLinkedListBaseAddr(dma, dma_stm32_id_to_stream(id),
(uint32_t)&Node_GPDMA_Channel);
LL_DMA_ConfigLinkUpdate(dma, dma_stm32_id_to_stream(id),
(LL_DMA_UPDATE_CTR1 | LL_DMA_UPDATE_CTR2 |
LL_DMA_UPDATE_CBR1 | LL_DMA_UPDATE_CSAR |
LL_DMA_UPDATE_CDAR | LL_DMA_UPDATE_CLLR),
(uint32_t)&Node_GPDMA_Channel);
LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id));
}
LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_TC(dma, dma_stm32_id_to_stream(id));
LL_DMA_EnableIT_USE(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_USE(dma, dma_stm32_id_to_stream(id));
LL_DMA_EnableIT_ULE(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_ULE(dma, dma_stm32_id_to_stream(id));
LL_DMA_EnableIT_DTE(dma, dma_stm32_id_to_stream(id)); LL_DMA_EnableIT_DTE(dma, dma_stm32_id_to_stream(id));
/* Enable Half-Transfer irq if circular mode is enabled */
if (config->head_block->source_reload_en) {
LL_DMA_EnableIT_HT(dma, dma_stm32_id_to_stream(id));
}
return ret; return ret;
} }