Skip to content

Commit 0ec325c

Browse files
committed
drivers: mspi_dw: Remove needless TXEIR check
This is a follow-up to commit f0f5f8c. There is no need to check if TXE interrupt flag is set before calling tx_dummy_bytes(), as the function can handle the case when it is called even though there is no room in the TX FIFO. On the other hand, the check may be actually harmful, as it may prevent adding more items to the TX FIFO while the SSI controller is waiting until the FIFO achieves its transfer start level. Remove the check then and exit the ISR loop when no dummy bytes could be written into the TX FIFO. Signed-off-by: Andrzej Głąbek <[email protected]>
1 parent 16f4d6c commit 0ec325c

File tree

1 file changed

+31
-7
lines changed

1 file changed

+31
-7
lines changed

drivers/mspi/mspi_dw.c

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ static void tx_data(const struct device *dev,
195195
dev_data->buf_pos = (uint8_t *)buf_pos;
196196
}
197197

198-
static bool tx_dummy_bytes(const struct device *dev)
198+
static bool tx_dummy_bytes(const struct device *dev, bool *repeat)
199199
{
200200
struct mspi_dw_data *dev_data = dev->data;
201201
const struct mspi_dw_config *dev_config = dev->config;
@@ -209,8 +209,17 @@ static bool tx_dummy_bytes(const struct device *dev)
209209
* FIFO to avoid overflowing it; `max_queued_dummy_bytes` accounts
210210
* that one byte that can be partially received, thus not included
211211
* in the value from the RXFLR register.
212+
* This check also handles the case when the function is called but
213+
* the TX FIFO is already filled up (fifo_room == 0).
212214
*/
213215
if (fifo_room <= rx_fifo_items) {
216+
if (repeat) {
217+
/* If no dummy bytes can be sent now, there is no point
218+
* in repeating the loop that reads the RX FIFO.
219+
*/
220+
*repeat = false;
221+
}
222+
214223
return false;
215224
}
216225
fifo_room -= rx_fifo_items;
@@ -329,7 +338,9 @@ static void handle_fifos(const struct device *dev)
329338
finished = true;
330339
}
331340
} else {
332-
for (;;) {
341+
bool repeat = true;
342+
343+
do {
333344
/* Always read everything from the RX FIFO, regardless
334345
* of the interrupt status.
335346
* tx_dummy_bytes() subtracts the number of items that
@@ -363,19 +374,28 @@ static void handle_fifos(const struct device *dev)
363374
break;
364375
}
365376

366-
if (dev_data->dummy_bytes == 0 ||
367-
!(int_status & RISR_TXEIR_BIT)) {
377+
/* If there are still some dummy bytes to transmit,
378+
* always try to put some into the TX FIFO, no matter
379+
* what's the TXE interrupt status - the TX FIFO may be
380+
* filled above its threshold level (then its interrupt
381+
* flag is not set), but below its transfer start level,
382+
* so the controller may be waiting for more items to
383+
* appear there.
384+
*/
385+
if (dev_data->dummy_bytes == 0) {
368386
break;
369387
}
370388

371-
if (tx_dummy_bytes(dev)) {
389+
if (tx_dummy_bytes(dev, &repeat)) {
372390
/* All the required dummy bytes were written
373391
* to the FIFO; disable the TXE interrupt,
374392
* as it's no longer needed.
375393
*/
376394
set_imr(dev, IMR_RXFIM_BIT);
377395
}
378-
}
396+
397+
/* Repeat the loop only if any dummy bytes were sent. */
398+
} while (repeat);
379399
}
380400

381401
if (finished) {
@@ -404,6 +424,8 @@ static void fifo_work_handler(struct k_work *work)
404424

405425
static void mspi_dw_isr(const struct device *dev)
406426
{
427+
NRF_P9->OUTSET = BIT(1);
428+
407429
#if defined(CONFIG_MSPI_DW_HANDLE_FIFOS_IN_SYSTEM_WORKQUEUE)
408430
struct mspi_dw_data *dev_data = dev->data;
409431
int rc;
@@ -420,6 +442,8 @@ static void mspi_dw_isr(const struct device *dev)
420442
#endif
421443

422444
vendor_specific_irq_clear(dev);
445+
446+
NRF_P9->OUTCLR = BIT(1);
423447
}
424448

425449
static int api_config(const struct mspi_dt_spec *spec)
@@ -1151,7 +1175,7 @@ static int start_next_packet(const struct device *dev, k_timeout_t timeout)
11511175
}
11521176

11531177
/* Prefill TX FIFO with any data we can */
1154-
if (dev_data->dummy_bytes && tx_dummy_bytes(dev)) {
1178+
if (dev_data->dummy_bytes && tx_dummy_bytes(dev, NULL)) {
11551179
imr = IMR_RXFIM_BIT;
11561180
} else if (packet->dir == MSPI_TX && packet->num_bytes) {
11571181
tx_data(dev, packet);

0 commit comments

Comments
 (0)