Skip to content

Commit a3530d6

Browse files
Johan Carlssonmmahadevan108
authored andcommitted
drivers: spi: mcux_flexcomm: use rxignore bit instead of dummy read.
when no rx data need to be read set the rxignore bits. with this change the dma setup is faster and no unnecessary dummy writes are done to memory. Signed-off-by: Johan Carlsson <[email protected]>
1 parent ff5afd8 commit a3530d6

File tree

1 file changed

+24
-19
lines changed

1 file changed

+24
-19
lines changed

drivers/spi/spi_mcux_flexcomm.c

Lines changed: 24 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -298,9 +298,6 @@ static int spi_mcux_configure(const struct device *dev,
298298
}
299299

300300
#ifdef CONFIG_SPI_MCUX_FLEXCOMM_DMA
301-
/* Dummy buffer used as a sink when rc buf is null */
302-
uint32_t dummy_rx_buffer;
303-
304301
/* This function is executed in the interrupt context */
305302
static void spi_mcux_dma_callback(const struct device *dev, void *arg,
306303
uint32_t channel, int status)
@@ -336,7 +333,7 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg,
336333

337334
static void spi_mcux_prepare_txlastword(uint32_t *txLastWord,
338335
const uint8_t *buf, const struct spi_config *spi_cfg,
339-
size_t len)
336+
size_t len, bool rx_ignore)
340337
{
341338
uint32_t word_size;
342339

@@ -349,6 +346,10 @@ static void spi_mcux_prepare_txlastword(uint32_t *txLastWord,
349346
*txLastWord = buf[len - 1U];
350347
}
351348

349+
if (rx_ignore) {
350+
*txLastWord |= (uint32_t)SPI_FIFOWR_RXIGNORE_MASK;
351+
}
352+
352353
*txLastWord |= (uint32_t)SPI_FIFOWR_EOT_MASK;
353354

354355
*txLastWord |= ((uint32_t)SPI_DEASSERT_ALL &
@@ -359,7 +360,8 @@ static void spi_mcux_prepare_txlastword(uint32_t *txLastWord,
359360
}
360361

361362
static void spi_mcux_prepare_txdummy(uint32_t *dummy, bool last_packet,
362-
const struct spi_config *spi_cfg)
363+
const struct spi_config *spi_cfg,
364+
bool rx_ignore)
363365
{
364366
uint32_t word_size;
365367

@@ -368,6 +370,9 @@ static void spi_mcux_prepare_txdummy(uint32_t *dummy, bool last_packet,
368370
if (last_packet) {
369371
*dummy |= (uint32_t)SPI_FIFOWR_EOT_MASK;
370372
}
373+
if (rx_ignore) {
374+
*dummy |= (uint32_t)SPI_FIFOWR_RXIGNORE_MASK;
375+
}
371376

372377
*dummy |= ((uint32_t)SPI_DEASSERT_ALL &
373378
(~(uint32_t)SPI_DEASSERTNUM_SSEL((uint32_t)spi_cfg->slave)));
@@ -377,7 +382,8 @@ static void spi_mcux_prepare_txdummy(uint32_t *dummy, bool last_packet,
377382
}
378383

379384
static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf,
380-
const struct spi_config *spi_cfg, size_t len, bool last_packet)
385+
const struct spi_config *spi_cfg, size_t len,
386+
bool last_packet, bool rx_ignore)
381387
{
382388
const struct spi_mcux_config *cfg = dev->config;
383389
struct spi_mcux_data *data = dev->data;
@@ -400,11 +406,11 @@ static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf,
400406
if (buf == NULL) {
401407
data->dummy_tx_buffer = 0;
402408
data->last_word = 0;
403-
spi_mcux_prepare_txdummy(&data->dummy_tx_buffer, last_packet, spi_cfg);
409+
spi_mcux_prepare_txdummy(&data->dummy_tx_buffer, last_packet, spi_cfg, rx_ignore);
404410

405411
if (last_packet &&
406412
((word_size > 8) ? (len > 2U) : (len > 1U))) {
407-
spi_mcux_prepare_txdummy(&data->last_word, last_packet, spi_cfg);
413+
spi_mcux_prepare_txdummy(&data->last_word, last_packet, spi_cfg, rx_ignore);
408414
blk_cfg->source_address = (uint32_t)&data->dummy_tx_buffer;
409415
blk_cfg->dest_address = (uint32_t)&base->FIFOWR;
410416
blk_cfg->block_size = (word_size > 8) ?
@@ -433,7 +439,7 @@ static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf,
433439
}
434440
} else {
435441
if (last_packet) {
436-
spi_mcux_prepare_txlastword(&data->last_word, buf, spi_cfg, len);
442+
spi_mcux_prepare_txlastword(&data->last_word, buf, spi_cfg, len, rx_ignore);
437443
}
438444
/* If last packet and data transfer frame is bigger then 1,
439445
* use dma descriptor to send the last data.
@@ -481,7 +487,7 @@ static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf,
481487

482488
uint32_t tmpData = 0U;
483489

484-
spi_mcux_prepare_txdummy(&tmpData, last_packet, spi_cfg);
490+
spi_mcux_prepare_txdummy(&tmpData, last_packet, spi_cfg, rx_ignore);
485491

486492
/* Setup the control info.
487493
* Halfword writes to just the control bits (offset 0xE22) doesn't push
@@ -514,21 +520,19 @@ static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf,
514520
/* retrieve active RX DMA channel (used in callback) */
515521
struct stream *stream = &data->dma_rx;
516522

523+
if (buf == NULL) {
524+
data->status_flags |= SPI_MCUX_FLEXCOMM_DMA_RX_DONE_FLAG;
525+
return 0;
526+
}
527+
517528
blk_cfg = &stream->dma_blk_cfg[0];
518529

519530
/* prepare the block for this RX DMA channel */
520531
memset(blk_cfg, 0, sizeof(struct dma_block_config));
521532
blk_cfg->block_size = len;
522533

523534
/* rx direction has periph as source and mem as dest. */
524-
if (buf == NULL) {
525-
/* if rx buff is null, then write data to dummy address. */
526-
blk_cfg->dest_address = (uint32_t)&dummy_rx_buffer;
527-
blk_cfg->dest_addr_adj = DMA_ADDR_ADJ_NO_CHANGE;
528-
} else {
529-
blk_cfg->dest_address = (uint32_t)buf;
530-
}
531-
535+
blk_cfg->dest_address = (uint32_t)buf;
532536
blk_cfg->source_address = (uint32_t)&base->FIFORD;
533537

534538
/* direction is given by the DT */
@@ -554,6 +558,7 @@ static int spi_mcux_dma_move_buffers(const struct device *dev, size_t len,
554558
const struct spi_config *spi_cfg, bool last_packet)
555559
{
556560
struct spi_mcux_data *data = dev->data;
561+
bool rx_ignore = data->ctx.rx_buf ? false : true;
557562
int ret;
558563

559564
ret = spi_mcux_dma_rx_load(dev, data->ctx.rx_buf, len);
@@ -563,7 +568,7 @@ static int spi_mcux_dma_move_buffers(const struct device *dev, size_t len,
563568
}
564569

565570
ret = spi_mcux_dma_tx_load(dev, data->ctx.tx_buf, spi_cfg,
566-
len, last_packet);
571+
len, last_packet, rx_ignore);
567572

568573
return ret;
569574
}

0 commit comments

Comments
 (0)