@@ -86,6 +86,7 @@ struct xlnx_quadspi_config {
86
86
void (* irq_config_func )(const struct device * dev );
87
87
uint8_t num_ss_bits ;
88
88
uint8_t num_xfer_bytes ;
89
+ uint16_t fifo_size ;
89
90
#if DT_ANY_INST_HAS_PROP_STATUS_OKAY (xlnx_startup_block )
90
91
bool startup_block ;
91
92
#endif
@@ -235,6 +236,7 @@ static void xlnx_quadspi_start_tx(const struct device *dev)
235
236
uint32_t spicr = 0U ;
236
237
uint32_t spisr ;
237
238
uint32_t dtr = 0U ;
239
+ uint32_t fifo_avail_words = config -> fifo_size ? config -> fifo_size : 1 ;
238
240
239
241
if (!spi_context_tx_on (ctx ) && !spi_context_rx_on (ctx )) {
240
242
/* All done, de-assert slave select */
@@ -285,9 +287,19 @@ static void xlnx_quadspi_start_tx(const struct device *dev)
285
287
xlnx_quadspi_write32 (dev , dtr , SPI_DTR_OFFSET );
286
288
spi_context_update_tx (ctx , config -> num_xfer_bytes , 1 );
287
289
288
- spisr = xlnx_quadspi_read32 (dev , SPISR_OFFSET );
289
- if (spisr & SPISR_TX_FULL ) {
290
- break ;
290
+ if (-- fifo_avail_words == 0 ) {
291
+ spisr = xlnx_quadspi_read32 (dev , SPISR_OFFSET );
292
+ if (spisr & SPISR_TX_FULL ) {
293
+ break ;
294
+ }
295
+ if (!config -> fifo_size ) {
296
+ fifo_avail_words = 1 ;
297
+ } else if (spisr & SPISR_TX_EMPTY ) {
298
+ fifo_avail_words = config -> fifo_size ;
299
+ } else {
300
+ fifo_avail_words = config -> fifo_size -
301
+ xlnx_quadspi_read32 (dev , SPI_TX_FIFO_OCR_OFFSET ) - 1 ;
302
+ }
291
303
}
292
304
}
293
305
@@ -396,19 +408,21 @@ static void xlnx_quadspi_isr(const struct device *dev)
396
408
const struct xlnx_quadspi_config * config = dev -> config ;
397
409
struct xlnx_quadspi_data * data = dev -> data ;
398
410
struct spi_context * ctx = & data -> ctx ;
399
- uint32_t temp ;
400
- uint32_t drr ;
411
+ uint32_t ipisr ;
401
412
402
413
/* Acknowledge interrupt */
403
- temp = xlnx_quadspi_read32 (dev , IPISR_OFFSET );
404
- xlnx_quadspi_write32 (dev , temp , IPISR_OFFSET );
414
+ ipisr = xlnx_quadspi_read32 (dev , IPISR_OFFSET );
415
+ xlnx_quadspi_write32 (dev , ipisr , IPISR_OFFSET );
405
416
406
- if (temp & IPIXR_DTR_EMPTY ) {
407
- temp = xlnx_quadspi_read32 (dev , SPISR_OFFSET );
417
+ if (ipisr & IPIXR_DTR_EMPTY ) {
418
+ uint32_t spisr = xlnx_quadspi_read32 (dev , SPISR_OFFSET );
419
+ /* RX FIFO occupancy register only exists if FIFO is implemented */
420
+ uint32_t rx_fifo_words = config -> fifo_size ?
421
+ xlnx_quadspi_read32 (dev , SPI_RX_FIFO_OCR_OFFSET ) + 1 : 1 ;
408
422
409
423
/* Read RX data */
410
- while (!(temp & SPISR_RX_EMPTY )) {
411
- drr = xlnx_quadspi_read32 (dev , SPI_DRR_OFFSET );
424
+ while (!(spisr & SPISR_RX_EMPTY )) {
425
+ uint32_t drr = xlnx_quadspi_read32 (dev , SPI_DRR_OFFSET );
412
426
413
427
if (spi_context_rx_buf_on (ctx )) {
414
428
switch (config -> num_xfer_bytes ) {
@@ -432,13 +446,17 @@ static void xlnx_quadspi_isr(const struct device *dev)
432
446
433
447
spi_context_update_rx (ctx , config -> num_xfer_bytes , 1 );
434
448
435
- temp = xlnx_quadspi_read32 (dev , SPISR_OFFSET );
449
+ if (-- rx_fifo_words == 0 ) {
450
+ spisr = xlnx_quadspi_read32 (dev , SPISR_OFFSET );
451
+ rx_fifo_words = config -> fifo_size ?
452
+ xlnx_quadspi_read32 (dev , SPI_RX_FIFO_OCR_OFFSET ) + 1 : 1 ;
453
+ }
436
454
}
437
455
438
456
/* Start next TX */
439
457
xlnx_quadspi_start_tx (dev );
440
458
} else {
441
- LOG_WRN ("unhandled interrupt, ipisr = 0x%08x" , temp );
459
+ LOG_WRN ("unhandled interrupt, ipisr = 0x%08x" , ipisr );
442
460
}
443
461
}
444
462
@@ -546,6 +564,7 @@ static const struct spi_driver_api xlnx_quadspi_driver_api = {
546
564
.num_ss_bits = DT_INST_PROP(n, xlnx_num_ss_bits), \
547
565
.num_xfer_bytes = \
548
566
DT_INST_PROP(n, xlnx_num_transfer_bits) / 8, \
567
+ .fifo_size = DT_INST_PROP_OR(n, fifo_size, 0), \
549
568
STARTUP_BLOCK_INIT(n) \
550
569
}; \
551
570
\
0 commit comments