Skip to content

drivers: spi: siwx91x: Add siwx91x SPI primary driver #88212

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

Merged
merged 4 commits into from
Apr 30, 2025

Conversation

smalae
Copy link
Collaborator

@smalae smalae commented Apr 6, 2025

Implement SPI primary driver for siwx91x device

@jerome-pouiller
Copy link
Collaborator

Hello @smalae,
The commit is large enough and touch to several components. Could you split it in atomic parts:

  • changes in the the clock framework
  • the SPI driver by itself
  • the changes in the DT
  • tests additions

@@ -296,6 +296,17 @@
prescaler = <1>;
status = "disabled";
};

gspi: spi@45030000 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I rather use the generic names for the DT labels: spi0: spi@45030000 {

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated

@smalae smalae force-pushed the silabs_siwx91x_spi_driver branch from 5cde70b to 6a096b8 Compare April 9, 2025 12:05
if SPI_SILABS_SIWX91X_GSPI

config SPI_SILABS_SIWX91X_GSPI_DMA
bool "SIWX91X MCU GSPI DMA Support"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Since this is a sub-option of SPI_SILABS_SIWX91X_GSPI, we can just say DMA Support (that's said, we have to clean up the names of all our drivers)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated

#ifdef CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA
struct gspi_siwx91x_dma_channel dma_rx;
struct gspi_siwx91x_dma_channel dma_tx;
#endif /* CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA */
Copy link
Collaborator

Choose a reason for hiding this comment

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

The comment is is not required if the condition is obvious.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed

int chan_nb;
struct dma_block_config dma_descriptors[CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA_MAX_BLOCKS];
};
#endif /* CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA */
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can define this struct unconditionally.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

int ret;
#ifdef CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA
int channel_filter;
#endif /* CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA */
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can use __maybe_unused rather than this #ifdef.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done

dma_release_channel(data->dma_tx.dma_dev, data->dma_tx.chan_nb);

/* Configure RX DMA channel */
if (data->dma_rx.chan_nb == GSPI_RX_UDMA_CH_NUM) {
Copy link
Collaborator

@jerome-pouiller jerome-pouiller Apr 9, 2025

Choose a reason for hiding this comment

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

This only works on siwx917. If the GSPI is used in another soc, this value will probably change. This is the job of the DT to provide this value. The driver can't verify it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed

}

/* Configure TX DMA channel */
if (data->dma_tx.chan_nb == GSPI_TX_UDMA_CH_NUM) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

See my previous comment.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Fixed

}

transaction_len -=
gspi_siwx91x_fill_desc(cfg, desc, NULL, transaction_len, is_tx, dfs);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Nitpick: we prefer to break between the arguments (as you did with gspi_siwx91x_fill_desc()):

		transaction_len -= gspi_siwx91x_fill_desc(cfg, desc, NULL,
							  transaction_len, is_tx, dfs);

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated


if (spi_context_tx_buf_on(&data->ctx)) {
if (dfs == 1) {
tx_frame = UNALIGNED_GET((uint8_t *)(data->ctx.tx_buf));
Copy link
Collaborator

Choose a reason for hiding this comment

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

UNALIGNED_GET() is not required with uint8_t.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Removed for uint8_t

uint16_t rx_frame;

tx_frame = gspi_siwx91x_next_tx(data, dfs);
gspi_siwx91x_send(cfg, (uint32_t)tx_frame);
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the cast is not required.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Updated

ret = gspi_siwx91x_transceive_dma(dev, config);
} else if (!asynchronous) {
/* Perform synchronous polling transceive */
ret = gspi_siwx91x_transceive_polling_sync(dev, &data->ctx);
Copy link
Collaborator

Choose a reason for hiding this comment

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

spi_transceive_async() is not about being irq based (or in reverse: spi_transceive() is not meant to be in polling mode).

The only difference on the 2 is that the _async will return asap, and use a callback to signal when the transfer is done, while the other is just a blocking call: but it does not mention anywhere that it should be polling. This is a common misunderstanding, I guess we'll need no detail that in the api file.

So remove the polling stuff, just use your dma version (an irq based if dma is not available would be nice).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thank you for the suggestion! I agree that using the DMA version for the sync API is the right approach. I've implemented this change, replacing the default polling mechanism for synchronous operations. However, switching to synchronous with IRQs, instead of DMA, presents a challenge. Large data transfers can trigger a lot of IRQs, which is not an issue when DMA is used. Is it acceptable to retain polling as a fallback for cases where the DMA component isn't available? This will allow users to quickly perform basic driver checks without requiring the DMA component.

@jerome-pouiller jerome-pouiller self-requested a review April 10, 2025 10:13
Clock driver changes required for initializing the SPI clock
for the siwx91x driver

Signed-off-by: Sai Santhosh Malae <[email protected]>
@smalae smalae force-pushed the silabs_siwx91x_spi_driver branch from 6a096b8 to 1bc2624 Compare April 23, 2025 07:05
@smalae smalae requested a review from tbursztyka April 23, 2025 07:16
@smalae smalae closed this Apr 23, 2025
@smalae smalae reopened this Apr 23, 2025
Copy link
Collaborator

@jerome-pouiller jerome-pouiller left a comment

Choose a reason for hiding this comment

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

The code is pleasant to read. My comments are mostly nitpicking.

smalae added 3 commits April 24, 2025 11:39
Implement SPI driver for siwx91x device

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

Signed-off-by: Sai Santhosh Malae <[email protected]>
1. Add board config and overlay files
2. Update testcase.yaml

Signed-off-by: Sai Santhosh Malae <[email protected]>
@smalae smalae force-pushed the silabs_siwx91x_spi_driver branch from 1bc2624 to c7a6854 Compare April 24, 2025 06:11
@jhedberg jhedberg self-assigned this Apr 30, 2025
@kartben kartben merged commit 8e57cc6 into zephyrproject-rtos:main Apr 30, 2025
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants