From e78729609dbdf598fa2f6459a983fd856fc28a8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrzej=20G=C5=82=C4=85bek?= Date: Tue, 10 Jun 2025 15:04:51 +0200 Subject: [PATCH] drivers: mspi_dw: Add support for RX dummy cycles in single line mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Support for 8 dummy cycles in a single line RX transaction is required for the standard JEDEC Read SFDP command. The SSI controller does not support dummy cycles in Standard SPI mode, but the driver can simulate those by just sending a dummy data byte. Signed-off-by: Andrzej Głąbek --- drivers/mspi/mspi_dw.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/mspi/mspi_dw.c b/drivers/mspi/mspi_dw.c index 019f613218e..adc59e765b1 100644 --- a/drivers/mspi/mspi_dw.c +++ b/drivers/mspi/mspi_dw.c @@ -844,13 +844,16 @@ static int start_next_packet(const struct device *dev, k_timeout_t timeout) (dev_data->xfer.cmd_length != 0 || dev_data->xfer.addr_length != 0)) { uint32_t rx_total_bytes; + uint32_t dummy_cycles = dev_data->xfer.rx_dummy; dev_data->bytes_to_discard = dev_data->xfer.cmd_length - + dev_data->xfer.addr_length; + + dev_data->xfer.addr_length + + dummy_cycles / 8; rx_total_bytes = dev_data->bytes_to_discard + packet->num_bytes; - dev_data->dummy_bytes = packet->num_bytes; + dev_data->dummy_bytes = dummy_cycles / 8 + + packet->num_bytes; imr = IMR_TXEIM_BIT | IMR_RXFIM_BIT; tmod = CTRLR0_TMOD_TX_RX; @@ -862,11 +865,13 @@ static int start_next_packet(const struct device *dev, k_timeout_t timeout) tmod = CTRLR0_TMOD_RX; rx_fifo_threshold = MIN(packet_frames - 1, dev_config->rx_fifo_threshold); + + dev_data->spi_ctrlr0 |= + FIELD_PREP(SPI_CTRLR0_WAIT_CYCLES_MASK, + dev_data->xfer.rx_dummy); } dev_data->ctrlr0 |= FIELD_PREP(CTRLR0_TMOD_MASK, tmod); - dev_data->spi_ctrlr0 |= FIELD_PREP(SPI_CTRLR0_WAIT_CYCLES_MASK, - dev_data->xfer.rx_dummy); write_rxftlr(dev, FIELD_PREP(RXFTLR_RFT_MASK, rx_fifo_threshold)); @@ -1039,10 +1044,15 @@ static int _api_transceive(const struct device *dev, return -EINVAL; } - if (dev_data->standard_spi && - (req->rx_dummy != 0 || req->tx_dummy != 0)) { - LOG_ERR("Dummy cycles unsupported in single line mode"); - return -EINVAL; + if (dev_data->standard_spi) { + if (req->tx_dummy) { + LOG_ERR("TX dummy cycles unsupported in single line mode"); + return -EINVAL; + } + if (req->rx_dummy % 8) { + LOG_ERR("Unsupported RX (%u) dummy cycles", req->rx_dummy); + return -EINVAL; + } } else if (req->rx_dummy > SPI_CTRLR0_WAIT_CYCLES_MAX || req->tx_dummy > SPI_CTRLR0_WAIT_CYCLES_MAX) { LOG_ERR("Unsupported RX (%u) or TX (%u) dummy cycles",