diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 399254a..7ce8da0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -50,6 +50,15 @@ jobs: run: | west twister -s drivers.flash.common.default -p siwx917_rb4338a -x DTC_OVERLAY_FILE=$(pwd)/tests/drivers/flash/common/boards/siwx917_rb4338a.overlay -v --inline-logs + - name: Build DMA test + working-directory: zephyr-silabs + shell: bash + run: | + west twister -s drivers.dma.chan_blen_transfer -p siwx917_rb4338a -- \ + -DTC_OVERLAY_FILE=$(pwd)/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.overlay \ + -DEXTRA_CONF_FILE=$(pwd)/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.conf \ + -v --inline-logs + - name: Build Bluetooth samples working-directory: zephyr-silabs shell: bash diff --git a/.github/workflows/upstream-build.yml b/.github/workflows/upstream-build.yml index a9f330c..1f357bf 100644 --- a/.github/workflows/upstream-build.yml +++ b/.github/workflows/upstream-build.yml @@ -52,6 +52,15 @@ jobs: run: | west twister -s drivers.flash.common.default -p siwx917_rb4338a -x DTC_OVERLAY_FILE=$(pwd)/tests/drivers/flash/common/boards/siwx917_rb4338a.overlay -v --inline-logs + - name: Build DMA test + working-directory: zephyr-silabs + shell: bash + run: | + west twister -s drivers.dma.chan_blen_transfer -p siwx917_rb4338a -- \ + -DTC_OVERLAY_FILE=$(pwd)/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.overlay \ + -DEXTRA_CONF_FILE=$(pwd)/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.conf \ + -v --inline-logs + - name: Build Bluetooth samples working-directory: zephyr-silabs shell: bash diff --git a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml index b34b0f2..6cbf587 100644 --- a/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml +++ b/boards/silabs/radio_boards/siwx917_rb4338a/siwx917_rb4338a.yaml @@ -11,6 +11,7 @@ toolchain: supported: - gpio - i2c + - dma - wifi - bluetooth - flash diff --git a/drivers/CMakeLists.txt b/drivers/CMakeLists.txt index fd47aaf..5cbf42f 100644 --- a/drivers/CMakeLists.txt +++ b/drivers/CMakeLists.txt @@ -6,4 +6,5 @@ add_subdirectory(entropy) add_subdirectory(flash) add_subdirectory(gpio) add_subdirectory(pinctrl) +add_subdirectory(dma) add_subdirectory(wifi) diff --git a/drivers/dma/CMakeLists.txt b/drivers/dma/CMakeLists.txt new file mode 100644 index 0000000..5a12b31 --- /dev/null +++ b/drivers/dma/CMakeLists.txt @@ -0,0 +1,4 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +zephyr_library_sources_ifdef(CONFIG_DMA_SILABS_SIWX917 dma_silabs_siwx917.c) diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig new file mode 100644 index 0000000..a1dd45a --- /dev/null +++ b/drivers/dma/Kconfig @@ -0,0 +1,8 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +if DMA + +rsource "Kconfig.siwx917" + +endif diff --git a/drivers/dma/Kconfig.siwx917 b/drivers/dma/Kconfig.siwx917 new file mode 100644 index 0000000..112787d --- /dev/null +++ b/drivers/dma/Kconfig.siwx917 @@ -0,0 +1,14 @@ +# Copyright (c) 2024 Silicon Laboratories Inc. +# SPDX-License-Identifier: Apache-2.0 + +menuconfig DMA_SILABS_SIWX917 + bool "Silabs SiWx917 DMA driver" + default y + depends on DT_HAS_SILABS_SIWX917_DMA_ENABLED + help + Enable the High Power(HP)/Ultra Low Power(ULP) DMA driver for the Silabs SiWx917 SoC series. + +config DMA_SILABS_SIWX917_COMMON_INIT_PRIORITY + int "Common initialization priority" + depends on DMA_SILABS_SIWX917 + default 42 diff --git a/drivers/dma/dma_silabs_siwx917.c b/drivers/dma/dma_silabs_siwx917.c new file mode 100644 index 0000000..c404fe3 --- /dev/null +++ b/drivers/dma/dma_silabs_siwx917.c @@ -0,0 +1,418 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include +#include "rsi_rom_udma_wrapper.h" +#include "rsi_udma.h" +#include "sl_status.h" + +#define DT_DRV_COMPAT silabs_siwx917_dma +#define DMA_MAX_TRANSFER_COUNT 1024 +#define DMA_CH_PRIORITY_HIGH 1 +#define DMA_CH_PRIORITY_LOW 0 +#define VALID_BURST_LENGTH 0 +#define UDMA_ADDR_INC_NONE 0X03 + +LOG_MODULE_REGISTER(si91x_dma, CONFIG_DMA_LOG_LEVEL); + +struct dma_siwx917_config { + UDMA0_Type *reg; /* UDMA register base address */ + uint8_t channels; /* UDMA channel count */ + uint8_t irq_number; /* IRQ number */ + RSI_UDMA_DESC_T *sram_desc_addr; /* SRAM Address for UDMA Descriptor Storage */ + void (*irq_configure)(void); /* IRQ configure function */ +}; + +struct dma_siwx917_data { + UDMA_Channel_Info *chan_info; + dma_callback_t dma_callback; /* User callback */ + void *cb_data; /* User callback data */ + RSI_UDMA_DATACONTEXT_T dma_rom_buff; /* Buffer to store UDMA handle */ + /* related information */ +}; + +static inline int siwx917_dma_is_peripheral_request(uint32_t dir) +{ + if (dir == MEMORY_TO_MEMORY) { + return 0; + } + if (dir == MEMORY_TO_PERIPHERAL || dir == PERIPHERAL_TO_MEMORY) { + return 1; + } + return -1; +} + +static inline int siwx917_dma_data_width(uint32_t data_width) +{ + switch (data_width) { + case 1: + return SRC_SIZE_8; + case 2: + return SRC_SIZE_16; + case 4: + return SRC_SIZE_32; + default: + return -EINVAL; + } +} + +static inline int siwx917_dma_burst_length(uint32_t blen) +{ + switch (blen / 8) { + case 1: + return VALID_BURST_LENGTH; /* 8-bit burst */ + default: + return -EINVAL; + } +} + +static inline int siwx917_dma_addr_adjustment(uint32_t adjustment) +{ + switch (adjustment) { + case 0: + return 0; /* Addr Increment */ + case 2: + return UDMA_ADDR_INC_NONE; /* No Address increment */ + default: + return -EINVAL; + } +} + +static int dma_channel_config(const struct device *dev, RSI_UDMA_HANDLE_T udma_handle, + uint32_t channel, struct dma_config *config, + UDMA_Channel_Info *channel_info) +{ + const struct dma_siwx917_config *cfg = dev->config; + UDMA_RESOURCES udma_resources = { + .reg = cfg->reg, + .udma_irq_num = cfg->irq_number, + /* SRAM address where UDMA descriptor is stored */ + .desc = cfg->sram_desc_addr, + }; + RSI_UDMA_CHA_CONFIG_DATA_T channel_control = { + .transferType = UDMA_MODE_BASIC, + }; + RSI_UDMA_CHA_CFG_T channel_config = {}; + int status; + + channel_config.channelPrioHigh = config->channel_priority; + if (siwx917_dma_is_peripheral_request(config->channel_direction) < 0) { + return -EINVAL; + } + channel_config.periphReq = siwx917_dma_is_peripheral_request(config->channel_direction); + channel_config.dmaCh = channel; + if (channel_config.periphReq) { + /* Arbitration power for peripheral<->memory transfers */ + channel_control.rPower = ARBSIZE_1; + } else { + /* Arbitration power for mem-mem transfers */ + channel_control.rPower = ARBSIZE_1024; + } + /* Obtain the number of transfers */ + config->head_block->block_size /= config->source_data_size; + if (config->head_block->block_size >= DMA_MAX_TRANSFER_COUNT) { + /* Maximum number of transfers is 1024 */ + channel_control.totalNumOfDMATrans = DMA_MAX_TRANSFER_COUNT - 1; + } else { + channel_control.totalNumOfDMATrans = config->head_block->block_size; + } + if (siwx917_dma_data_width(config->source_data_size) < 0 || + siwx917_dma_data_width(config->dest_data_size) < 0) { + return -EINVAL; + } + if (siwx917_dma_burst_length(config->source_burst_length) < 0 || + siwx917_dma_burst_length(config->dest_burst_length) < 0) { + return -EINVAL; + } + channel_control.srcSize = siwx917_dma_data_width(config->source_data_size); + channel_control.dstSize = siwx917_dma_data_width(config->dest_data_size); + if (siwx917_dma_addr_adjustment(config->head_block->source_addr_adj) < 0 || + siwx917_dma_addr_adjustment(config->head_block->dest_addr_adj) < 0) { + return -EINVAL; + } + if (siwx917_dma_addr_adjustment(config->head_block->source_addr_adj) == 0) { + channel_control.srcInc = channel_control.srcSize; + } else { + channel_control.srcInc = UDMA_SRC_INC_NONE; + } + if (siwx917_dma_addr_adjustment(config->head_block->dest_addr_adj) == 0) { + channel_control.dstInc = channel_control.dstSize; + } else { + channel_control.dstInc = UDMA_DST_INC_NONE; + } + status = UDMAx_ChannelConfigure(&udma_resources, (uint8_t)channel, + config->head_block->source_address, + config->head_block->dest_address, + config->head_block->block_size, channel_control, + &channel_config, NULL, channel_info, udma_handle); + if (status) { + return -EIO; + } + return 0; +} + +/* Function to configure UDMA channel for transfer */ +static int dma_siwx917_configure(const struct device *dev, uint32_t channel, + struct dma_config *config) +{ + const struct dma_siwx917_config *cfg = dev->config; + struct dma_siwx917_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + int status; + + /* Expecting a fixed channel number between 0-31 for udma0 and 0-11 for udma1 */ + if (channel >= cfg->channels) { + return -EINVAL; + } + + /* Disable the channel before configuring */ + if (RSI_UDMA_ChannelDisable(udma_handle, channel) != 0) { + return -EIO; + } + + if (config->channel_priority != DMA_CH_PRIORITY_LOW && + config->channel_priority != DMA_CH_PRIORITY_HIGH) { + return -EINVAL; + } + + /* Configure dma channel for transfer */ + status = dma_channel_config(dev, udma_handle, channel, config, data->chan_info); + if (status) { + return status; + } + return 0; +} + +/* Function to reload UDMA channel for new transfer */ +static int dma_siwx917_reload(const struct device *dev, uint32_t channel, uint32_t src, + uint32_t dst, size_t size) +{ + const struct dma_siwx917_config *cfg = dev->config; + struct dma_siwx917_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + uint32_t desc_src_addr; + uint32_t desc_dst_addr; + uint32_t length; + RSI_UDMA_DESC_T *udma_table = cfg->sram_desc_addr; + + /* Expecting a fixed channel number between 0-31 for udma0 and 0-11 for udma1 */ + if (channel >= cfg->channels) { + return -EINVAL; + } + + /* Disable the channel before reloading transfer */ + if (RSI_UDMA_ChannelDisable(udma_handle, channel) != 0) { + return -EIO; + } + + /* Update new channel info to dev->data structure */ + data->chan_info[channel].SrcAddr = src; + data->chan_info[channel].DestAddr = dst; + data->chan_info[channel].Size = size; + + /* Update new transfer size to dev->data structure */ + if (size >= DMA_MAX_TRANSFER_COUNT) { + data->chan_info[channel].Cnt = DMA_MAX_TRANSFER_COUNT - 1; + } else { + data->chan_info[channel].Cnt = size; + } + /* Program the DMA descriptors with new transfer data information. */ + if (udma_table[channel].vsUDMAChaConfigData1.srcInc != UDMA_SRC_INC_NONE) { + length = data->chan_info[channel].Cnt + << udma_table[channel].vsUDMAChaConfigData1.srcInc; + desc_src_addr = src + (length - 1); + udma_table[channel].pSrcEndAddr = (void *)desc_src_addr; + } + if (udma_table[channel].vsUDMAChaConfigData1.dstInc != UDMA_SRC_INC_NONE) { + length = data->chan_info[channel].Cnt + << udma_table[channel].vsUDMAChaConfigData1.dstInc; + desc_dst_addr = dst + (length - 1); + udma_table[channel].pDstEndAddr = (void *)desc_dst_addr; + } + udma_table[channel].vsUDMAChaConfigData1.totalNumOfDMATrans = data->chan_info[channel].Cnt; + udma_table[channel].vsUDMAChaConfigData1.transferType = UDMA_MODE_BASIC; + + return 0; +} + +/* Function to start a DMA transfer */ +static int dma_siwx917_start(const struct device *dev, uint32_t channel) +{ + const struct dma_siwx917_config *cfg = dev->config; + RSI_UDMA_DESC_T *udma_table = cfg->sram_desc_addr; + struct dma_siwx917_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + + /* Expecting a fixed channel number between 0-31 for udma0 and 0-11 for udma1 */ + if (channel >= cfg->channels) { + return -EINVAL; + } + if (RSI_UDMA_ChannelEnable(udma_handle, channel) != 0) { + return -EINVAL; + } + + /* Check if the transfer type is memory-memory */ + if (udma_table[channel].vsUDMAChaConfigData1.srcInc != UDMA_SRC_INC_NONE && + udma_table[channel].vsUDMAChaConfigData1.dstInc != UDMA_DST_INC_NONE) { + /* Apply software trigger to start transfer */ + cfg->reg->CHNL_SW_REQUEST |= BIT(channel); + } + return 0; +} + +/* Function to stop a DMA transfer */ +static int dma_siwx917_stop(const struct device *dev, uint32_t channel) +{ + const struct dma_siwx917_config *cfg = dev->config; + struct dma_siwx917_data *data = dev->data; + void *udma_handle = &data->dma_rom_buff; + + /* Expecting a fixed channel number between 0-31 for udma0 and 0-11 for udma1 */ + if (channel >= cfg->channels) { + return -EINVAL; + } + if (RSI_UDMA_ChannelDisable(udma_handle, channel) != 0) { + return -EIO; + } + return 0; +} + +/* Function to fetch DMA channel status */ +static int dma_siwx917_get_status(const struct device *dev, uint32_t channel, + struct dma_status *stat) +{ + const struct dma_siwx917_config *cfg = dev->config; + RSI_UDMA_DESC_T *udma_table = cfg->sram_desc_addr; + + /* Expecting a fixed channel number between 0-31 for udma0 and 0-11 for udma1 */ + if (channel >= cfg->channels) { + return -EINVAL; + } + /* Read the channel status register */ + if (cfg->reg->CHANNEL_STATUS_REG & BIT(channel)) { + stat->busy = 1; + } else { + stat->busy = 0; + } + + /* Obtain the transfer direction from channel descriptors */ + if (udma_table[channel].vsUDMAChaConfigData1.srcInc == UDMA_SRC_INC_NONE) { + stat->dir = PERIPHERAL_TO_MEMORY; + } else if (udma_table[channel].vsUDMAChaConfigData1.dstInc == UDMA_DST_INC_NONE) { + stat->dir = MEMORY_TO_PERIPHERAL; + } else { + stat->dir = MEMORY_TO_MEMORY; + } + return 0; +} + +/* Function to initialize DMA peripheral */ +static int dma_siwx917_init(const struct device *dev) +{ + const struct dma_siwx917_config *cfg = dev->config; + struct dma_siwx917_data *data = dev->data; + void *udma_handle = NULL; + UDMA_RESOURCES udma_resources = { + .reg = cfg->reg, /* UDMA register base address */ + .udma_irq_num = cfg->irq_number, + .desc = cfg->sram_desc_addr, + }; + + udma_handle = UDMAx_Initialize(&udma_resources, udma_resources.desc, NULL, + (uint32_t *)&data->dma_rom_buff); + if (udma_handle != &data->dma_rom_buff) { + return -EINVAL; + } + + /* Connect the DMA interrupt */ + cfg->irq_configure(); + + if (UDMAx_DMAEnable(&udma_resources, udma_handle) != 0) { + return -EBUSY; + } + return 0; +} + +static void dma_siwx917_isr(const struct device *dev) +{ + const struct dma_siwx917_config *cfg = dev->config; + struct dma_siwx917_data *data = dev->data; + UDMA_RESOURCES udma_resources = { + .reg = cfg->reg, + .udma_irq_num = cfg->irq_number, + .desc = cfg->sram_desc_addr, + }; + uint8_t channel; + + /* Disable the IRQ to prevent the ISR from being triggered by */ + /* interrupts from other DMA channels */ + irq_disable(cfg->irq_number); + channel = find_lsb_set(cfg->reg->UDMA_DONE_STATUS_REG); + /* Identify the interrupt channel */ + if (!channel || channel > cfg->channels) { + goto out; + } + /* find_lsb_set() returns 1 indexed value */ + channel -= 1; + if (data->chan_info[channel].Cnt == data->chan_info[channel].Size) { + if (data->dma_callback) { + /* Transfer complete, call user callback */ + data->dma_callback(dev, data->cb_data, channel, 0); + } + cfg->reg->UDMA_DONE_STATUS_REG = BIT(channel); + } else { + /* Call UDMA ROM IRQ handler. */ + ROMAPI_UDMA_WRAPPER_API->uDMAx_IRQHandler(&udma_resources, udma_resources.desc, + data->chan_info); + /* Is a Memory-to-memory Transfer */ + if (udma_resources.desc[channel].vsUDMAChaConfigData1.srcInc != UDMA_SRC_INC_NONE && + udma_resources.desc[channel].vsUDMAChaConfigData1.dstInc != UDMA_DST_INC_NONE) { + /* Set the software trigger bit for starting next transfer */ + cfg->reg->CHNL_SW_REQUEST |= BIT(channel); + } + } +out: + /* Enable the IRQ to restore interrupt functionality for other DMA channels */ + irq_enable(cfg->irq_number); +} + +/* Store the Si91x DMA APIs */ +static const struct dma_driver_api siwx917_dma_driver_api = { + .config = dma_siwx917_configure, + .reload = dma_siwx917_reload, + .start = dma_siwx917_start, + .stop = dma_siwx917_stop, + .get_status = dma_siwx917_get_status, +}; + +#define SIWX917_DMA_INIT(inst) \ + static UDMA_Channel_Info dma##inst##_channel_info[DT_INST_PROP(inst, dma_channels)]; \ + static struct dma_siwx917_data dma##inst##_data = { \ + .chan_info = dma##inst##_channel_info, \ + }; \ + static void siwx917_dma##inst##_irq_configure(void) \ + { \ + IRQ_CONNECT(DT_INST_IRQ(inst, irq), DT_INST_IRQ(inst, priority), dma_siwx917_isr, \ + DEVICE_DT_INST_GET(inst), 0); \ + irq_enable(DT_INST_IRQ(inst, irq)); \ + } \ + static const struct dma_siwx917_config dma##inst##_cfg = { \ + .reg = (UDMA0_Type *)DT_INST_REG_ADDR(inst), \ + .channels = DT_INST_PROP(inst, dma_channels), \ + .irq_number = DT_INST_PROP_BY_IDX(inst, interrupts, 0), \ + .sram_desc_addr = (RSI_UDMA_DESC_T *)DT_INST_PROP(inst, silabs_sram_desc_addr), \ + .irq_configure = siwx917_dma##inst##_irq_configure, \ + }; \ + DEVICE_DT_INST_DEFINE(inst, &dma_siwx917_init, NULL, &dma##inst##_data, &dma##inst##_cfg, \ + PRE_KERNEL_1, CONFIG_DMA_INIT_PRIORITY, &siwx917_dma_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SIWX917_DMA_INIT) diff --git a/dts/arm/silabs/siwg917.dtsi b/dts/arm/silabs/siwg917.dtsi index ccdace2..4dec4e8 100644 --- a/dts/arm/silabs/siwg917.dtsi +++ b/dts/arm/silabs/siwg917.dtsi @@ -221,6 +221,32 @@ compatible = "silabs,siwx917-rng"; reg = <0x45090000 0x8>; }; + + udma0: dma@44030000 { + compatible = "silabs,siwx917-dma"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x44030000 0x82C>; + interrupts = <33 0>; + interrupt-names = "udma0"; + silabs,sram-desc-addr = <0x2fc00>; + #dma-cells = < 1>; + dma-channels = <32>; + status = "disabled"; + }; + + udma1: dma@24078000 { + compatible = "silabs,siwx917-dma"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x24078000 0x82C>; + interrupts = <10 0>; + interrupt-names = "udma1"; + silabs,sram-desc-addr = <0x24061c00>; + #dma-cells = < 1>; + dma-channels = <12>; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/dma/silabs,siwx917-dma.yaml b/dts/bindings/dma/silabs,siwx917-dma.yaml new file mode 100644 index 0000000..37251b3 --- /dev/null +++ b/dts/bindings/dma/silabs,siwx917-dma.yaml @@ -0,0 +1,26 @@ +description: Silabs SiWx917 DMA node + +compatible: "silabs,siwx917-dma" + +include: dma-controller.yaml + +properties: + reg: + required: true + + silabs,sram-desc-addr: + type: int + required: true + description: | + SRAM Address for UDMA Descriptor Storage. This address must correspond to the location + of the udma_addr0 section in the linker script for the udma0 node, and the udma_addr1 + section for the udma1 node. Ensure that the value specified for the SRAM address matches + the respective section defined in the linker file for each UDMA node, as this alignment + is critical for proper descriptor management and data transfer. + + "#dma-cells": + const: 1 + +# Parameter syntax +dma-cells: + - channel diff --git a/modules/hal_silabs/wiseconnect/CMakeLists.txt b/modules/hal_silabs/wiseconnect/CMakeLists.txt index 90dae8a..45bfef0 100644 --- a/modules/hal_silabs/wiseconnect/CMakeLists.txt +++ b/modules/hal_silabs/wiseconnect/CMakeLists.txt @@ -58,6 +58,14 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_SILABS_SIWX917 ${DEVICE_DIR}/silabs/si91x/mcu/drivers/peripheral_drivers/src/rsi_rng.c ) +zephyr_library_sources_ifdef(CONFIG_DMA_SILABS_SIWX917 + ${DEVICE_DIR}/silabs/si91x/mcu/drivers/rom_driver/src/rsi_rom_table_si91x.c +) + +zephyr_compile_definitions_ifdef(CONFIG_DMA_SILABS_SIWX917 + UDMA_ROMDRIVER_PRESENT +) + if(CONFIG_WIFI_SIWX917) zephyr_compile_definitions_ifdef(CONFIG_NET_IPV6 diff --git a/soc/silabs/silabs_siwx917/siwg917/linker.ld b/soc/silabs/silabs_siwx917/siwg917/linker.ld index 0b37a04..5d12a17 100644 --- a/soc/silabs/silabs_siwx917/siwg917/linker.ld +++ b/soc/silabs/silabs_siwx917/siwg917/linker.ld @@ -5,10 +5,29 @@ */ #include +MEMORY +{ + udma0 (rwx) : ORIGIN = 0x0002fc00, LENGTH = 0x00000400 + udma1 (rwx) : ORIGIN = 0x24061c00, LENGTH = 0x00000400 +} + SECTIONS { .common_tcm_code : { *(.common_tcm_code*) } > FLASH + + /* These regions of SRAM is where the UDMA descriptors are stored. The corresponding + section must be properly declared in the linker script to ensure correct data transfer + and proper functioning of the UDMA module */ + .udma_addr0 : + { + *(.udma_addr0*) + } > udma0 AT> FLASH + + .udma_addr1 : + { + *(.udma_addr1*) + } > udma1 AT> FLASH } diff --git a/soc/silabs/silabs_siwx917/siwg917/soc.c b/soc/silabs/silabs_siwx917/siwg917/soc.c index dcac51d..3d58bef 100644 --- a/soc/silabs/silabs_siwx917/siwg917/soc.c +++ b/soc/silabs/silabs_siwx917/siwg917/soc.c @@ -48,6 +48,14 @@ int silabs_siwx917_init(void) RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_I2C); RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_I2C_CLK, ENABLE_STATIC_CLK); #endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(udma0), okay) + RSI_PS_M4ssPeriPowerUp(M4SS_PWRGATE_ULP_EFUSE_PERI); + RSI_CLK_PeripheralClkEnable(M4CLK, UDMA_CLK, ENABLE_STATIC_CLK); +#endif +#if DT_NODE_HAS_STATUS(DT_NODELABEL(udma1), okay) + RSI_PS_UlpssPeriPowerUp(ULPSS_PWRGATE_ULP_UDMA); + RSI_ULPSS_PeripheralEnable(ULPCLK, ULP_UDMA_CLK, ENABLE_STATIC_CLK); +#endif return 0; } diff --git a/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.conf b/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.conf new file mode 100644 index 0000000..542bad6 --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.conf @@ -0,0 +1,4 @@ +CONFIG_DMA_TRANSFER_CHANNEL_NR_0=1 +CONFIG_DMA_TRANSFER_CHANNEL_NR_1=2 +CONFIG_DMA_LOOP_TRANSFER_NUMBER_OF_DMAS=2 +CONFIG_DMA_TRANSFER_BURST16=n diff --git a/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.overlay b/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.overlay new file mode 100644 index 0000000..c1de2ed --- /dev/null +++ b/tests/drivers/dma/chan_blen_transfer/boards/siwx917_rb4338a.overlay @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2024 Silicon Laboratories Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +tst_dma0: &udma0 { + status = "okay"; +}; + +tst_dma1: &udma1 { + status = "okay"; +}; diff --git a/west.yml b/west.yml index da196bf..eb169af 100644 --- a/west.yml +++ b/west.yml @@ -11,7 +11,7 @@ manifest: projects: - name: hal_silabs remote: silabs - revision: 72fb0e677fb0ab09981c1217e38c4246ad4b5dcd + revision: b5394a199887fd213b53c89281d6a7eadc5f65a2 path: modules/hal/silabs - name: zephyr remote: zephyrproject-rtos