Skip to content

Silabs siwx91x gpdma driver #93556

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

smalae
Copy link
Contributor

@smalae smalae commented Jul 23, 2025

Enable GPDMA driver for siwx91x device

Copy link

github-actions bot commented Jul 23, 2025

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
hal_silabs zephyrproject-rtos/hal_silabs@13343bc (main) zephyrproject-rtos/hal_silabs#120 zephyrproject-rtos/hal_silabs#120/files

DNM label due to: 1 project with PR revision

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@github-actions github-actions bot added manifest manifest-hal_silabs DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Jul 23, 2025
@smalae smalae force-pushed the silabs-siwx91x-gpdma-driver branch 3 times, most recently from 15f1e38 to e8d84a9 Compare July 23, 2025 15:19
@smalae smalae marked this pull request as ready for review July 23, 2025 15:51
@smalae smalae force-pushed the silabs-siwx91x-gpdma-driver branch from e8d84a9 to 395aa21 Compare July 25, 2025 05:16
Comment on lines 98 to 101
if (blen < 4) {
return AHBBURST_SIZE_1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that feels not right, if a user want a blen of 2 (I don't know why), you have a burst size of 1, it's tricky for him no ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the final burst length (blen) is calculated as the least value between ahb_burst and the source/destination burst length. Code is updated now.

static ATOMIC_DEFINE(dma_channels_atomic_##inst, \
DT_INST_PROP(inst, silabs_dma_channel_count)); \
SYS_MEM_BLOCKS_DEFINE_STATIC(desc_pool_##inst, 32, \
CONFIG_GPDMA_SILABS_SIWX91X_DESCRIPTOR_COUNT, 512); \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

alignment of the mem block needs to be that high ? descriptor for gpdma have such constraint ? or is it because of the usage of contiguous sys mem block ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most tests in WiseConnect align descriptor arrays to 512 or 1024 bytes. However, I changed the alignment value to 32 bytes and ran the tests, which appear to work correctly. The alignment has now been updated to 32 bytes.

#define SIWX91X_GPDMA_INIT(inst) \
static ATOMIC_DEFINE(dma_channels_atomic_##inst, \
DT_INST_PROP(inst, silabs_dma_channel_count)); \
SYS_MEM_BLOCKS_DEFINE_STATIC(desc_pool_##inst, 32, \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sizeof(RSI_GPDMA_DESC_T)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Each descriptor block address must be 32-byte aligned for GPDMA. Since sizeof(RSI_GPDMA_DESC_T) is 20 bytes, without 32-byte alignment for each block, some test cases are failing.


if (channel_int_status & abort_mask) {
RSI_GPDMA_AbortChannel(GPDMA_HANDLE, channel);
cfg->reg->GLOBAL.INTERRUPT_STAT_REG = abort_mask;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for all reg operation, please use sys_read(...) and sys_write(...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

data->chan_info[channel].desc_count);
data->chan_info[channel].chan_base_desc = NULL;
data->chan_info[channel].desc_count = 0;
cfg->reg->GLOBAL.INTERRUPT_STAT_REG = done_mask;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

don't you only want to clean the interrupt for the channel ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing 0 to these register bits has no effect.

return 0;
}

static void siwx91x_gpdma_isr(const struct device *dev)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how do you handle it if you have multiple channel isr ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ISR will be triggered multiple times for multiple channel interrupts. The ISR will continue to be retriggered until all channel bit fields in cfg->reg->GLOBAL.INTERRUPT_STAT_REG are cleared. I tested this scenario in the SPI transfer case


data->chan_info[channel].dma_callback = config->dma_callback;
data->chan_info[channel].cb_data = config->user_data;
atomic_set_bit(data->dma_ctx.atomic, channel);
Copy link
Contributor

@teburd teburd Jul 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The atomic bitset here is being used elsewhere for channel acquire/release calls by default. If the bit isn't set while configuring, and the caller is preempted, its possible to race on obtaining and configuring the channel.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this should be handled through channel request and release APIs. Removed this call here.

return -EINVAL;
}

if (!atomic_test_bit(data->dma_ctx.atomic, channel)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You shouldn't need these atomic ops in start/stop

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

xfer_cfg->chnlCtrlConfig.srcFifoMode = 1;
}

if (sys_mem_blocks_alloc_contiguous(data->gpdma_desc_pool, 1, &gpdma_desc_addr)) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mem_block allocator does not have an internal lock. The only acceptable lock you can use here (as DMA APIs should absolutely be ISR ok) would be a spin lock.

Alternatively you could have statically allocated descriptors for each channel and use them as needed. Though this might leave more "dead" descriptors around could be done without locks.

It'd be nicer to me to see a struct descriptor type with a well understood size rather than a void * being used.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I implemented a spin lock and updated the descriptor type for 'gpdma_desc_addr'. I will use mem_block as it handles the allocation/deallocation of memory blocks better than statically allocated ones.

@smalae smalae force-pushed the silabs-siwx91x-gpdma-driver branch 3 times, most recently from d71fb6e to b80bcc8 Compare July 30, 2025 15:27
Clock driver changes required for initializing the GPDMA clock
for the siwx91x driver

Signed-off-by: Sai Santhosh Malae <[email protected]>
@smalae smalae force-pushed the silabs-siwx91x-gpdma-driver branch from b80bcc8 to 7078699 Compare August 9, 2025 08:20
Comment on lines 150 to 157
key = k_spin_lock(&data->mem_blocks_lock);

if (sys_mem_blocks_alloc_contiguous(data->gpdma_desc_pool, 1,
(void **)&gpdma_desc_addr)) {
if (pPrevDesc == NULL) {
return -EINVAL;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like a bug to me. You're returning from the function before unlocking the spin lock.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated

uint16_t max_xfer_size = GPDMA_DESC_MAX_TRANSFER_SIZE - config->source_data_size;
const struct dma_block_config *block_addr = config->head_block;
RSI_GPDMA_DESC_T *gpdma_desc_addr = NULL;
RSI_GPDMA_DESC_T *pPrevDesc = NULL;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a good reason to use CamelCase and Hungarian notation for this variable name? (which violates the Zephyr coding style)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it is updated now

smalae added 3 commits August 9, 2025 20:40
Implement GPDMA driver for siwx91x device

Signed-off-by: Sai Santhosh Malae <[email protected]>
1. Create a YAML file for gpdma node
2. Add GPDMA node in the siwx917.dtsi

Signed-off-by: Sai Santhosh Malae <[email protected]>
Add siwx917_rb4338a board overlay and config files

Signed-off-by: Sai Santhosh Malae <[email protected]>
@smalae smalae force-pushed the silabs-siwx91x-gpdma-driver branch from 7078699 to d6c57ac Compare August 9, 2025 15:15
@zephyrbot zephyrbot added the area: SPI SPI bus label Aug 9, 2025
@zephyrbot zephyrbot requested review from decsny and tbursztyka August 9, 2025 15:16
@smalae smalae force-pushed the silabs-siwx91x-gpdma-driver branch from d6c57ac to 05ff70c Compare August 9, 2025 15:20
@smalae smalae requested a review from jhedberg August 9, 2025 15:23
@smalae smalae closed this Aug 11, 2025
@smalae smalae reopened this Aug 11, 2025
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Clock Control area: DMA Direct Memory Access area: SPI SPI bus DNM (manifest) This PR should not be merged (controlled by action-manifest) manifest manifest-hal_silabs platform: Silabs Silicon Labs
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants