Skip to content

Commit e425b3d

Browse files
danieldegrassefabiobaltieri
authored andcommitted
drivers: mspi: mspi_dw: improve reliability of CS signal
The designware controller has an *interesting* implementation of the CS signal- CS will be de-asserted whenever the TX FIFO is empty, so slower cores may see CS de-assert prematurely if they cannot keep pace with their SPI peripheral. To help reduce odds of de-assertion, implement the following changes: - don't write SER bit until directly before we enable interrupts, so that transfers don't start early - prefix the TX FIFO before writing SER, so the FIFO can drain a bit before have to service an interrupt Signed-off-by: Daniel DeGrasse <[email protected]>
1 parent 9c829a1 commit e425b3d

File tree

1 file changed

+11
-1
lines changed

1 file changed

+11
-1
lines changed

drivers/mspi/mspi_dw.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -940,7 +940,6 @@ static int start_next_packet(const struct device *dev, k_timeout_t timeout)
940940
write_spi_ctrlr0(dev, dev_data->spi_ctrlr0);
941941
write_baudr(dev, dev_data->baudr);
942942
write_rx_sample_dly(dev, dev_data->rx_sample_dly);
943-
write_ser(dev, BIT(dev_data->dev_id->dev_idx));
944943

945944
if (xip_enabled) {
946945
write_ssienr(dev, SSIENR_SSIC_EN_BIT);
@@ -1027,8 +1026,17 @@ static int start_next_packet(const struct device *dev, k_timeout_t timeout)
10271026
}
10281027
}
10291028

1029+
/* Prefill TX FIFO with any data we can */
1030+
if (dev_data->dummy_bytes && tx_dummy_bytes(dev)) {
1031+
imr = IMR_RXFIM_BIT;
1032+
} else if (packet->dir == MSPI_TX && packet->num_bytes) {
1033+
tx_data(dev, packet);
1034+
}
1035+
10301036
/* Enable interrupts now and wait until the packet is done. */
10311037
write_imr(dev, imr);
1038+
/* Write SER to start transfer */
1039+
write_ser(dev, BIT(dev_data->dev_id->dev_idx));
10321040

10331041
rc = k_sem_take(&dev_data->finished, timeout);
10341042
if (read_risr(dev) & RISR_RXOIR_BIT) {
@@ -1058,6 +1066,8 @@ static int start_next_packet(const struct device *dev, k_timeout_t timeout)
10581066
} else {
10591067
write_ssienr(dev, 0);
10601068
}
1069+
/* Clear SER */
1070+
write_ser(dev, 0);
10611071

10621072
if (dev_data->dev_id->ce.port) {
10631073
int rc2;

0 commit comments

Comments
 (0)