-
Notifications
You must be signed in to change notification settings - Fork 8.3k
drivers: spi: siwx91x: SPI driver fixes to enable higher burst rates #99860
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
base: main
Are you sure you want to change the base?
drivers: spi: siwx91x: SPI driver fixes to enable higher burst rates #99860
Conversation
The GSPI and QSPI peripherals run on the interface PLL clock. To ensure correct operation, the interface PLL frequency should be set to 160 MHz. This provides a base clock of 80 MHz to the QSPI peripheral, which matches its required operating frequency. The GSPI peripheral can continue to operate at higher frequencies as it receives the full interface PLL clock. Signed-off-by: Sai Santhosh Malae <[email protected]>
3b4530b to
3453c6f
Compare
3453c6f to
45a9da9
Compare
| clock_control_subsys_t clock_subsys; | ||
| const struct pinctrl_dev_config *pcfg; | ||
| uint8_t mosi_overrun __aligned(4); | ||
| uint8_t mosi_overrun __aligned(32); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This update ensures proper buffer alignment when using the SI91x GPDMA driver. A separate commit has been created to address this issue explicitly.
| uint32_t *div_out) | ||
| { | ||
| /* Calculate divider that ensures freq <= requested */ | ||
| uint32_t divider = (clock_hz + (2U * requested_hz) - 1U) / (2U * requested_hz); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
uint32_t divider = DIV_ROUND_UP(clock_hz, 2 * requested_hz);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated
| /* Compute the actual achievable frequency */ | ||
| uint32_t actual_hz = clock_hz / (2U * divider); | ||
|
|
||
| if (divider == 0U) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If divider == 0, actual_hz = clock_hz / (2U * divider) has already raised a fault.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| } | ||
|
|
||
| return 1; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe this function is more complex than required. I believe we can get the same result with:
static int gspi_siwx91x_burst_size_buf(const struct spi_buf *spi_buf)
{
int burst_len = 4;
if (!ctx->current_tx[i].len || !ctx->current_tx[i].buf) {
return burst_len;
}
burst_len = MIN(burst_len, BIT(find_lsb_set(spi_buf->buf) - 1));
burst_len = MIN(burst_len, BIT(find_lsb_set(spi_buf->len) - 1));
return burst_len;
}
static int gspi_siwx91x_burst_size(struct spi_context *ctx)
{
int burst_len = 4;
for (int i = 0; i < ctx->tx_count; i++) {
burst_len = MIN(burst_len, gspi_siwx91x_burst_size_buf(ctx->current_tx + i));
}
for (int i = 0; i < ctx->rx_count; i++) {
burst_len = MIN(burst_len, gspi_siwx91x_burst_size_buf(ctx->current_rx + i));
}
return burst_len;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated as per the suggestion with minor adjustments.
| - CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA=y | ||
| - CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=26 | ||
| extra_args: | ||
| - DTC_OVERLAY_FILE="boards/siwx917_rb4338a.overlay" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest to introduce boards/siwx917_rb4342a.overlay rather than using extra_args:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
| - siwx917_rb4342a | ||
| extra_configs: | ||
| - CONFIG_SPI_SILABS_SIWX91X_GSPI_DMA=y | ||
| - CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING=26 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant with the .conf file, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed
Add gspi_siwx91x_pick_lower_freq() to select the nearest lower supported GSPI clock frequency based on the requested value. The GSPI clock can operate only at discrete frequencies such as 80 MHz, 40 MHz, 26.6 MHz, 20 MHz, and so on (80 MHz divided by integer factors). If the requested frequency does not match one of these valid steps, it is rounded down to the nearest lower supported frequency. The driver now logs both the requested and the actual programmed frequency along with the divider value, helping users verify the effective SPI clock configuration. Signed-off-by: Sai Santhosh Malae <[email protected]>
45a9da9 to
1ceb193
Compare
Enable higher SPI burst sizes when using GPDMA to improve throughput. Bursts are only enabled when both TX and RX channels use GPDMA and the SPI clock frequency is at least 10 MHz, as DMA flow control is unreliable at lower SPI rates. Signed-off-by: Sai Santhosh Malae <[email protected]>
Updated mosi_overrun alignment from 4 bytes to 32 bytes to ensure compatibility with the GPDMA driver. This prevents alignment-related errors during DMA transfers. Signed-off-by: Sai Santhosh Malae <[email protected]>
Swap the write and read data paths within the GSPI controller to ensure correct data is seen on the SPI lines during 16-bit transfers. Signed-off-by: Sai Santhosh Malae <[email protected]>
Guard callback registration with CONFIG_SPI_ASYNC to avoid build error for blocking SPI transfers using DMA Signed-off-by: Sai Santhosh Malae <[email protected]>
Increase CONFIG_SPI_IDEAL_TRANSFER_DURATION_SCALING to compensate for the additional burst size calculation in the SPI driver, which slightly increases transfer time. Signed-off-by: Sai Santhosh Malae <[email protected]>
Add overlay and config files for siwx917_rb4342a to enable the spi_loopback test. Signed-off-by: Sai Santhosh Malae <[email protected]>
1ceb193 to
05fa966
Compare
|



Uh oh!
There was an error while loading. Please reload this page.