Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions drivers/dma/dma_silabs_siwx91x_gpdma.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,16 +132,22 @@ static int siwx91x_gpdma_desc_config(struct siwx19x_gpdma_data *data,
const struct dma_config *config,
const RSI_GPDMA_DESC_T *xfer_cfg, uint32_t channel)
{
uint16_t max_xfer_size = GPDMA_DESC_MAX_TRANSFER_SIZE - config->source_data_size;
int operation_width = config->source_data_size * config->source_burst_length;
const struct dma_block_config *block_addr = config->head_block;
RSI_GPDMA_DESC_T *cur_desc = NULL;
RSI_GPDMA_DESC_T *prev_desc = NULL;
k_spinlock_key_t key;
int ret;

for (int i = 0; i < config->block_count; i++) {
if (block_addr->block_size > max_xfer_size) {
LOG_ERR("Maximum xfer size should be <= %d\n", max_xfer_size);
if (!IS_ALIGNED(block_addr->source_address, config->source_burst_length) ||
!IS_ALIGNED(block_addr->dest_address, config->dest_burst_length) ||
!IS_ALIGNED(block_addr->block_size, operation_width)) {
LOG_ERR("Buffer not aligned\n");
goto free_desc;
}
if (block_addr->block_size >= GPDMA_DESC_MAX_TRANSFER_SIZE) {
LOG_ERR("Buffer too large (%d bytes)\n", block_addr->block_size);
goto free_desc;
}

Expand Down
44 changes: 23 additions & 21 deletions drivers/spi/spi_silabs_siwx91x_gspi.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ LOG_MODULE_REGISTER(spi_siwx91x_gspi, CONFIG_SPI_LOG_LEVEL);

#define GSPI_MAX_BAUDRATE_FOR_DYNAMIC_CLOCK 110000000
#define GSPI_MAX_BAUDRATE_FOR_POS_EDGE_SAMPLE 40000000
#define GSPI_DMA_MAX_DESCRIPTOR_TRANSFER_SIZE 1024
#define GSPI_DMA_MAX_DESCRIPTOR_TRANSFER_SIZE 4096

/* Warning for unsupported configurations */
#if defined(CONFIG_SPI_ASYNC) && !defined(CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA)
Expand All @@ -34,6 +34,7 @@ LOG_MODULE_REGISTER(spi_siwx91x_gspi, CONFIG_SPI_LOG_LEVEL);
/* Structure for DMA configuration */
struct gspi_siwx91x_dma_channel {
const struct device *dma_dev;
uint8_t dma_slot;
int chan_nb;
#ifdef CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA
struct dma_block_config dma_descriptors[CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA_MAX_BLOCKS];
Expand All @@ -45,7 +46,7 @@ struct gspi_siwx91x_config {
const struct device *clock_dev;
clock_control_subsys_t clock_subsys;
const struct pinctrl_dev_config *pcfg;
uint8_t mosi_overrun;
uint8_t mosi_overrun __aligned(4);
};

struct gspi_siwx91x_data {
Expand All @@ -56,7 +57,7 @@ struct gspi_siwx91x_data {

#ifdef CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA
/* Placeholder buffer for unused RX data */
static volatile uint8_t empty_buffer;
static volatile uint8_t empty_buffer __aligned(4);
#endif

static bool spi_siwx91x_is_dma_enabled_instance(const struct device *dev)
Expand Down Expand Up @@ -217,13 +218,15 @@ static int gspi_siwx91x_dma_config(const struct device *dev,
{
struct dma_config cfg = {
.channel_direction = is_tx ? MEMORY_TO_PERIPHERAL : PERIPHERAL_TO_MEMORY,
.channel_priority = 1,
.complete_callback_en = 0,
.source_data_size = dfs,
.dest_data_size = dfs,
.source_burst_length = dfs,
.dest_burst_length = dfs,
.source_burst_length = 1,
.dest_burst_length = 1,
.block_count = block_count,
.head_block = channel->dma_descriptors,
.dma_slot = channel->dma_slot,
.dma_callback = !is_tx ? &gspi_siwx91x_dma_rx_callback : NULL,
.user_data = (void *)dev,
};
Expand All @@ -233,7 +236,7 @@ static int gspi_siwx91x_dma_config(const struct device *dev,

static uint32_t gspi_siwx91x_fill_desc(const struct gspi_siwx91x_config *cfg,
struct dma_block_config *new_blk_cfg, uint8_t *buffer,
size_t requested_transaction_size, bool is_tx, uint8_t dfs)
size_t requested_transaction_size, bool is_tx)
{

/* Set-up source and destination address with increment behavior */
Expand Down Expand Up @@ -261,19 +264,19 @@ static uint32_t gspi_siwx91x_fill_desc(const struct gspi_siwx91x_config *cfg,
}
}

/* Setup max transfer according to requested transaction size.
* Will top if bigger than the maximum transfer size.
/* The underlying DMA can sent a bit less than 4k of data depending of the data size of and
* the burst length. We avoid complex computation, 32 bytes fits all the cases.
*/
new_blk_cfg->block_size =
MIN(requested_transaction_size, GSPI_DMA_MAX_DESCRIPTOR_TRANSFER_SIZE * dfs);
new_blk_cfg->block_size = MIN(requested_transaction_size,
GSPI_DMA_MAX_DESCRIPTOR_TRANSFER_SIZE - 32);
return new_blk_cfg->block_size;
}

struct dma_block_config *gspi_siwx91x_fill_data_desc(const struct gspi_siwx91x_config *cfg,
struct dma_block_config *desc,
const struct spi_buf buffers[],
int buffer_count, size_t transaction_len,
bool is_tx, uint8_t dfs)
bool is_tx)
{
__ASSERT(transaction_len > 0, "Not supported");

Expand All @@ -294,8 +297,7 @@ struct dma_block_config *gspi_siwx91x_fill_data_desc(const struct gspi_siwx91x_c
/* Calculate the buffer pointer with the current offset */
buffer = buffers[i].buf ? (uint8_t *)buffers[i].buf + offset : NULL;
/* Fill the descriptor with the buffer data and update the offset */
offset += gspi_siwx91x_fill_desc(cfg, desc, buffer, buffers[i].len - offset, is_tx,
dfs);
offset += gspi_siwx91x_fill_desc(cfg, desc, buffer, buffers[i].len - offset, is_tx);
/* If the end of the current buffer is reached, move to the next buffer */
if (offset == buffers[i].len) {
transaction_len -= offset;
Expand All @@ -314,8 +316,7 @@ struct dma_block_config *gspi_siwx91x_fill_data_desc(const struct gspi_siwx91x_c
return NULL;
}

transaction_len -= gspi_siwx91x_fill_desc(cfg, desc, NULL,
transaction_len, is_tx, dfs);
transaction_len -= gspi_siwx91x_fill_desc(cfg, desc, NULL, transaction_len, is_tx);
if (transaction_len) {
desc = desc->next_block;
}
Expand Down Expand Up @@ -351,7 +352,7 @@ static int gspi_siwx91x_prepare_dma_channel(const struct device *spi_dev,
gspi_siwx91x_reset_desc(channel);

desc = gspi_siwx91x_fill_data_desc(cfg, channel->dma_descriptors, buffer, buffer_count,
padded_transaction_size, is_tx, dfs);
padded_transaction_size, is_tx);
if (!desc) {
return -ENOMEM;
}
Expand Down Expand Up @@ -407,7 +408,8 @@ static int gspi_siwx91x_transceive_dma(const struct device *dev, const struct sp
return -EINVAL;
}

/* Reset the Rx and Tx FIFO register */
cfg->reg->GSPI_FIFO_THRLD_b.RFIFO_RESET = 1;
cfg->reg->GSPI_FIFO_THRLD_b.WFIFO_RESET = 1;
cfg->reg->GSPI_FIFO_THRLD = 0;

ret = gspi_siwx91x_prepare_dma_transaction(dev, padded_transaction_size);
Expand Down Expand Up @@ -637,8 +639,8 @@ static DEVICE_API(spi, gspi_siwx91x_driver_api) = {
.dma_##dir = { \
.chan_nb = DT_INST_DMAS_CELL_BY_NAME(index, dir, channel), \
.dma_dev = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(index, dir)), \
.dma_slot = DT_DMAS_CELL_BY_NAME_OR(index, dir, slot, 0), \
},

#define SPI_SILABS_SIWX91X_GSPI_DMA_CHANNEL(index, dir) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(index, dmas), \
(SPI_SILABS_SIWX91X_GSPI_DMA_CHANNEL_INIT(index, dir)), ())
Expand All @@ -652,9 +654,9 @@ static DEVICE_API(spi, gspi_siwx91x_driver_api) = {
SPI_CONTEXT_INIT_LOCK(gspi_data_##inst, ctx), \
SPI_CONTEXT_INIT_SYNC(gspi_data_##inst, ctx), \
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(inst), ctx) \
SPI_SILABS_SIWX91X_GSPI_DMA_CHANNEL(inst, rx) \
SPI_SILABS_SIWX91X_GSPI_DMA_CHANNEL(inst, tx) \
}; \
SPI_SILABS_SIWX91X_GSPI_DMA_CHANNEL(inst, rx) \
SPI_SILABS_SIWX91X_GSPI_DMA_CHANNEL(inst, tx) \
}; \
static const struct gspi_siwx91x_config gspi_config_##inst = { \
.reg = (GSPI0_Type *)DT_INST_REG_ADDR(inst), \
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst)), \
Expand Down
46 changes: 23 additions & 23 deletions dts/arm/silabs/siwg917.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,20 @@
status = "disabled";
};

ulpdma: dma@24078000 {
compatible = "silabs,siwx91x-dma";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x24078000 0x82C>;
interrupts = <10 0>;
interrupt-names = "ulpdma";
clocks = <&clock0 SIWX91X_CLK_ULP_DMA>;
silabs,sram-region = <&sram_dma1>;
#dma-cells = <1>;
dma-channels = <12>;
status = "disabled";
};

dma0: dma@44030000 {
compatible = "silabs,siwx91x-dma";
#address-cells = <1>;
Expand All @@ -307,17 +321,17 @@
status = "disabled";
};

ulpdma: dma@24078000 {
compatible = "silabs,siwx91x-dma";
gpdma: gpdma@21080000 {
compatible = "silabs,gpdma";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x24078000 0x82C>;
interrupts = <10 0>;
interrupt-names = "ulpdma";
clocks = <&clock0 SIWX91X_CLK_ULP_DMA>;
silabs,sram-region = <&sram_dma1>;
#dma-cells = <1>;
dma-channels = <12>;
reg = <0x21080000 0x1720>;
interrupts = <31 0>;
interrupt-names = "gpdma";
clocks = <&clock0 SIWX91X_CLK_GPDMA0>;
silabs,channel-reg-base = <0x21081004>;
silabs,dma-channel-count = <8>;
#dma-cells = <2>;
status = "disabled";
};

Expand Down Expand Up @@ -414,20 +428,6 @@
#io-channel-cells = <1>;
status = "disabled";
};

gpdma0: gpdma@21080000 {
compatible = "silabs,gpdma";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x21080000 0x1720>;
interrupts = <31 0>;
interrupt-names = "gpdma0";
clocks = <&clock0 SIWX91X_CLK_GPDMA0>;
silabs,channel-reg-base = <0x21081004>;
silabs,dma-channel-count = <8>;
#dma-cells = <2>;
status = "disabled";
};
};
};

Expand Down
4 changes: 2 additions & 2 deletions tests/drivers/spi/spi_loopback/boards/siwx917_dk2605a.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
pinctrl-0 = <&spi0_default>;
pinctrl-names = "default";

dmas = <&dma0 11>, <&dma0 10>;
dmas = <&dma1 0 11>, <&dma1 1 10>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this too should be replaced with gpdma

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, CI also noticed it.

dma-names = "tx", "rx";

slow@0 {
Expand All @@ -36,6 +36,6 @@
};
};

&dma0 {
&dma1 {
status = "okay";
};
4 changes: 2 additions & 2 deletions tests/drivers/spi/spi_loopback/boards/siwx917_rb4338a.overlay
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
pinctrl-0 = <&spi0_default>;
pinctrl-names = "default";

dmas = <&dma0 11>, <&dma0 10>;
dmas = <&gpdma 0 11>, <&gpdma 1 10>;
dma-names = "tx", "rx";

slow@0 {
Expand All @@ -36,6 +36,6 @@
};
};

&dma0 {
&gpdma {
status = "okay";
};