From 546a59b449bb758aae363ce25617551ae1b3fa28 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 18 Feb 2025 10:30:22 -0600 Subject: [PATCH 1/8] spi_nxp_lpspi: Reset/clock peripheral If there are HAL definitions available, do these two things: Ungate the clock for the device from the zephyr driver. Eventually it would be better to have a clocks property in the LPSPI DT node and get the resources from there rather than the HAL. Some platforms require the peripheral to be reset at system level, add code to do this. Eventually it would be more ideal to have Zephyr reset drivers for all of the NXP platforms and use DT to describe the reset resources, but for now we can just do this to get the LPSPI supported. Signed-off-by: Declan Snyder --- .../spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c index 4d8450b1cae90..13bb5a52bb85e 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c @@ -9,6 +9,49 @@ LOG_MODULE_REGISTER(spi_mcux_lpspi_common, CONFIG_SPI_LOG_LEVEL); #include "spi_nxp_lpspi_priv.h" +#if defined(LPSPI_RSTS) || defined(LPSPI_CLOCKS) +static LPSPI_Type *const lpspi_bases[] = LPSPI_BASE_PTRS; +#endif + +#ifdef LPSPI_RSTS +static const reset_ip_name_t lpspi_resets[] = LPSPI_RSTS; + +static inline reset_ip_name_t lpspi_get_reset(LPSPI_Type *const base) +{ + reset_ip_name_t rst = -1; /* invalid initial value */ + + ARRAY_FOR_EACH(lpspi_bases, idx) { + if (lpspi_bases[idx] == base) { + rst = lpspi_resets[idx]; + break; + } + } + + __ASSERT_NO_MSG(rst != -1); + return rst; + +} +#endif + +#ifdef LPSPI_CLOCKS +static const clock_ip_name_t lpspi_clocks[] = LPSPI_CLOCKS; + +static inline clock_ip_name_t lpspi_get_clock(LPSPI_Type *const base) +{ + clock_ip_name_t clk = -1; /* invalid initial value */ + + ARRAY_FOR_EACH(lpspi_bases, idx) { + if (lpspi_bases[idx] == base) { + clk = lpspi_clocks[idx]; + break; + } + } + + __ASSERT_NO_MSG(clk != -1); + return clk; +} +#endif + void lpspi_wait_tx_fifo_empty(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); @@ -128,6 +171,17 @@ int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cf return 0; } +static void lpspi_module_system_init(LPSPI_Type *base) +{ +#ifdef LPSPI_CLOCKS + CLOCK_EnableClock(lpspi_get_clock(base)); +#endif + +#ifdef LPSPI_RSTS + RESET_ReleasePeripheralReset(lpspi_get_reset(base)); +#endif +} + int spi_nxp_init_common(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); @@ -144,6 +198,8 @@ int spi_nxp_init_common(const struct device *dev) return -ENODEV; } + lpspi_module_system_init(base); + err = spi_context_cs_configure_all(&data->ctx); if (err < 0) { return err; From 1d16f8af4d816a9866175acd31c4810f0f838ef1 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 27 Mar 2025 17:02:38 -0500 Subject: [PATCH 2/8] spi_nxp_lpspi: Prevent edge case causing DMA error Stop the transfer with error if at any point there is some execution reached where transfer is being set up for 0 length, this can cause problems where for example eDMA set up with this nonsense 0 length channels can get an infinite error interrupt. And this is probably an erroneously crafted transfer request anyways. Signed-off-by: Declan Snyder --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c index 0b204f486910e..1b58eb8f54986 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c @@ -102,6 +102,14 @@ static inline int spi_mcux_dma_rxtx_load(const struct device *dev) size_t next_chunk_size = spi_context_max_continuous_chunk(ctx); int ret = 0; + if (next_chunk_size == 0) { + /* In case both buffers are 0 length, we should not even be here + * and attempting to set up a DMA transfer like this will cause + * errors that lock up the system in some cases with eDMA. + */ + return -ENODATA; + } + ret = spi_mcux_dma_tx_load(dev, ctx->tx_buf, next_chunk_size); if (ret != 0) { return ret; @@ -223,7 +231,11 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi spi_context_cs_control(ctx, true); ret = spi_mcux_dma_next_fill(dev); - if (ret) { + if (ret == -ENODATA) { + /* No transfer to do? So just exit */ + ret = 0; + goto out; + } else if (ret) { goto out; } From 5bc4d26069c921eba48b9740e25024bf7b0a0a6b Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Thu, 27 Mar 2025 10:26:24 -0500 Subject: [PATCH 3/8] spi_nxp_lpspi: Fix DMA driver async return We should not release context until transfer ends. The code previously would return from wait_for_completion and then release the context. This is only supposed to be done in the dma callback except for the case of error in the transceive call. For async transfer this was most likely always happening wrong and probably broken for multi threads trying to access the bus due to this premature release of the context. Also we should not enable CS and leave enabled in case of error, move CS enable to after the error check. Signed-off-by: Declan Snyder --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c index 1b58eb8f54986..6fbe031e518f9 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c @@ -204,6 +204,7 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t spi_context_cs_control(ctx, false); LPSPI_FlushFifo(base, true, true); spi_context_complete(ctx, spi_dev, status); + spi_context_release(ctx, status); } static int transceive_dma(const struct device *dev, const struct spi_config *spi_cfg, @@ -224,12 +225,6 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, 1); - if (!(IS_ENABLED(CONFIG_SOC_FAMILY_NXP_IMXRT) || IS_ENABLED(CONFIG_SOC_FAMILY_KINETIS))) { - base->TCR |= LPSPI_TCR_CONT_MASK; - } - - spi_context_cs_control(ctx, true); - ret = spi_mcux_dma_next_fill(dev); if (ret == -ENODATA) { /* No transfer to do? So just exit */ @@ -239,11 +234,20 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi goto out; } + if (!(IS_ENABLED(CONFIG_SOC_FAMILY_NXP_IMXRT) || IS_ENABLED(CONFIG_SOC_FAMILY_KINETIS))) { + base->TCR |= LPSPI_TCR_CONT_MASK; + } + + spi_context_cs_control(ctx, true); + LPSPI_FlushFifo(base, true, true); LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); ret = spi_context_wait_for_completion(ctx); + if (ret >= 0) { + return ret; + } out: spi_context_release(ctx, ret); return ret; From 116e04342148ec15fa2f06143a3037f4b9ab2618 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 18 Feb 2025 09:55:04 -0600 Subject: [PATCH 4/8] spi_nxp_lpspi: Convert DMA version to native code Convert the DMA-based LPSPI driver to native code. Signed-off-by: Declan Snyder --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c index 6fbe031e518f9..7b3f34645abd1 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c @@ -64,8 +64,7 @@ static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, si stream->dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL; } - /* Dest is always LPSPI tx fifo */ - blk_cfg->dest_address = LPSPI_GetTxRegisterAddress(base); + blk_cfg->dest_address = (uint32_t) &(base->TDR); return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); } @@ -87,7 +86,7 @@ static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf, size_t l blk_cfg->dest_address = (uint32_t)buf; } - blk_cfg->source_address = LPSPI_GetRxRegisterAddress(base); + blk_cfg->source_address = (uint32_t) &(base->RDR); return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); } @@ -180,8 +179,10 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t return; } - while ((IS_ENABLED(CONFIG_SOC_FAMILY_NXP_IMXRT) || IS_ENABLED(CONFIG_SOC_FAMILY_KINETIS)) && - (LPSPI_GetStatusFlags(base) & kLPSPI_ModuleBusyFlag)) { + + while ((IS_ENABLED(CONFIG_SOC_FAMILY_NXP_IMXRT) || + IS_ENABLED(CONFIG_SOC_FAMILY_KINETIS)) && + (base->SR & LPSPI_SR_MBF_MASK)) { /* wait until module is idle */ } @@ -198,11 +199,11 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t error: LOG_ERR("DMA callback error with channel %d err %d.", channel, status); done: - LPSPI_DisableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); + base->DER &= ~(LPSPI_DER_TDDE_MASK | LPSPI_DER_RDDE_MASK); base->TCR &= ~LPSPI_TCR_CONT_MASK; lpspi_wait_tx_fifo_empty(spi_dev); spi_context_cs_control(ctx, false); - LPSPI_FlushFifo(base, true, true); + base->CR |= LPSPI_CR_RTF_MASK | LPSPI_CR_RRF_MASK; spi_context_complete(ctx, spi_dev, status); spi_context_release(ctx, status); } @@ -240,9 +241,9 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi spi_context_cs_control(ctx, true); - LPSPI_FlushFifo(base, true, true); + base->CR |= LPSPI_CR_RTF_MASK | LPSPI_CR_RRF_MASK; - LPSPI_EnableDMA(base, kLPSPI_TxDmaEnable | kLPSPI_RxDmaEnable); + base->DER |= LPSPI_DER_TDDE_MASK | LPSPI_DER_RDDE_MASK; ret = spi_context_wait_for_completion(ctx); if (ret >= 0) { From e8ebbad487853cb41ed2f8e67765b64ce7b90b7a Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 18 Feb 2025 10:18:17 -0600 Subject: [PATCH 5/8] spi_nxp_lpspi: Convert CPU version to native code Convert the CPU-based lpspi driver to native code. Signed-off-by: Declan Snyder --- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c | 35 +++++++++---------- .../spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h | 2 ++ 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c index 88dd3c33e1ce5..f5a6c305431f0 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c @@ -35,7 +35,7 @@ static inline void lpspi_rx_word_write_bytes(const struct device *dev, size_t of struct spi_context *ctx = &data->ctx; uint8_t num_bytes = MIN(lpspi_data->word_size_bytes, ctx->rx_len); uint8_t *buf = ctx->rx_buf + offset; - uint32_t word = LPSPI_ReadData(base); + uint32_t word = base->RDR; if (!spi_context_rx_buf_on(ctx) && spi_context_rx_on(ctx)) { /* receive no actual data if rx buf is NULL */ @@ -77,7 +77,7 @@ static inline void lpspi_handle_rx_irq(const struct device *dev) uint8_t total_words_read = 0; uint8_t words_read; - LPSPI_ClearStatusFlags(base, kLPSPI_RxDataReadyFlag); + base->SR = LPSPI_SR_RDF_MASK; LOG_DBG("RX FIFO: %d, RX BUF: %p", rx_fsr, ctx->rx_buf); @@ -91,8 +91,8 @@ static inline void lpspi_handle_rx_irq(const struct device *dev) LOG_DBG("RX done %d words to spi buf", total_words_written); if (spi_context_rx_len_left(ctx) == 0) { - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_RxInterruptEnable); - LPSPI_FlushFifo(base, false, true); + base->IER &= ~LPSPI_IER_RDIE_MASK; + base->CR |= LPSPI_CR_RRF_MASK; /* flush rx fifo */ } } @@ -121,7 +121,7 @@ static inline void lpspi_fill_tx_fifo(const struct device *dev) size_t offset; for (offset = 0; offset < bytes_in_xfer; offset += lpspi_data->word_size_bytes) { - LPSPI_WriteData(base, lpspi_next_tx_word(dev, offset)); + base->TDR = lpspi_next_tx_word(dev, offset); } LOG_DBG("Filled TX FIFO to %d words (%d bytes)", lpspi_data->fill_len, offset); @@ -134,7 +134,7 @@ static void lpspi_fill_tx_fifo_nop(const struct device *dev) struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; for (int i = 0; i < lpspi_data->fill_len; i++) { - LPSPI_WriteData(base, 0); + base->TDR = 0; } LOG_DBG("Filled TX fifo with %d NOPs", lpspi_data->fill_len); @@ -169,10 +169,10 @@ static inline void lpspi_handle_tx_irq(const struct device *dev) spi_context_update_tx(ctx, lpspi_data->word_size_bytes, lpspi_data->fill_len); - LPSPI_ClearStatusFlags(base, kLPSPI_TxDataRequestFlag); + base->SR = LPSPI_SR_TDF_MASK; if (!spi_context_tx_on(ctx)) { - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable); + base->IER &= ~LPSPI_IER_TDIE_MASK; return; } @@ -183,16 +183,16 @@ static void lpspi_isr(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); const struct spi_mcux_config *config = dev->config; - uint32_t status_flags = LPSPI_GetStatusFlags(base); struct spi_mcux_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; + uint32_t status_flags = base->SR; - if (status_flags & kLPSPI_RxDataReadyFlag) { + if (status_flags & LPSPI_SR_RDF_MASK) { lpspi_handle_rx_irq(dev); } - if (status_flags & kLPSPI_TxDataRequestFlag) { + if (status_flags & LPSPI_SR_TDF_MASK) { lpspi_handle_tx_irq(dev); } @@ -250,15 +250,15 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg goto error; } - LPSPI_FlushFifo(base, true, true); - LPSPI_ClearStatusFlags(base, (uint32_t)kLPSPI_AllStatusFlag); - LPSPI_DisableInterrupts(base, (uint32_t)kLPSPI_AllInterruptEnable); + base->CR |= LPSPI_CR_RTF_MASK | LPSPI_CR_RRF_MASK; /* flush fifos */ + base->IER = 0; /* disable all interrupts */ + base->FCR = 0; /* set watermarks to 0 */ + base->SR |= LPSPI_INTERRUPT_BITS; LOG_DBG("Starting LPSPI transfer"); spi_context_cs_control(ctx, true); - LPSPI_SetFifoWatermarks(base, 0, 0); - LPSPI_Enable(base, true); + base->CR |= LPSPI_CR_MEN_MASK; /* keep the chip select asserted until the end of the zephyr xfer */ base->TCR |= LPSPI_TCR_CONT_MASK; @@ -268,8 +268,7 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg /* start the transfer sequence which are handled by irqs */ lpspi_next_tx_fill(dev); - LPSPI_EnableInterrupts(base, (uint32_t)kLPSPI_TxInterruptEnable | - (uint32_t)kLPSPI_RxInterruptEnable); + base->IER |= LPSPI_IER_TDIE_MASK | LPSPI_IER_RDIE_MASK; ret = spi_context_wait_for_completion(ctx); if (ret >= 0) { diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h index e02db078028f8..493b147b66841 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h @@ -24,6 +24,8 @@ #define LPSPI_CHIP_SELECT_COUNT 4 #define LPSPI_MIN_FRAME_SIZE_BITS 8 +#define LPSPI_INTERRUPT_BITS GENMASK(8, 13) + /* Required by DEVICE_MMIO_NAMED_* macros */ #define DEV_CFG(_dev) ((const struct spi_mcux_config *)(_dev)->config) #define DEV_DATA(_dev) ((struct spi_mcux_data *)(_dev)->data) From b1ed4a174ad6804a6972a5a2358bdf5d05d46a60 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 18 Feb 2025 10:32:46 -0600 Subject: [PATCH 6/8] spi_nxp_lpspi: Refactor validation args to func Minor refactor to make a separate function to validate configuration arguments. Signed-off-by: Declan Snyder --- .../spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c | 58 +++++++++++-------- 1 file changed, 35 insertions(+), 23 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c index 13bb5a52bb85e..2840b3e454132 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c @@ -69,29 +69,14 @@ int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg) return 0; } -int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg) +static inline int lpspi_validate_xfer_args(const struct spi_config *spi_cfg) { - const struct spi_mcux_config *config = dev->config; - struct spi_mcux_data *data = dev->data; - struct spi_context *ctx = &data->ctx; - LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); uint32_t word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); - bool configured = ctx->config != NULL; - lpspi_master_config_t master_config; - uint32_t clock_freq; - int ret; - - /* fast path to avoid reconfigure */ - /* TODO: S32K3 errata ERR050456 requiring module reset before every transfer, - * investigate alternative workaround so we don't have this latency for S32. - */ - if (spi_context_configured(ctx, spi_cfg) && !IS_ENABLED(CONFIG_SOC_FAMILY_NXP_S32)) { - return 0; - } + uint32_t pcs = spi_cfg->slave; if (spi_cfg->operation & SPI_HALF_DUPLEX) { /* the IP DOES support half duplex, need to implement driver support */ - LOG_ERR("Half-duplex not supported"); + LOG_WRN("Half-duplex not supported"); return -ENOTSUP; } @@ -103,22 +88,49 @@ int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cf * Minimum hardware word size is 2. Since this driver is intended to work * for 32 bit platforms, and 64 bits is max size, then only 33 and 1 are invalid. */ - LOG_ERR("Word size %d not allowed", word_size); + LOG_WRN("Word size %d not allowed", word_size); return -EINVAL; } - if (spi_cfg->slave > (LPSPI_CHIP_SELECT_COUNT - 1)) { - LOG_ERR("Peripheral %d select exceeds max %d", spi_cfg->slave, - LPSPI_CHIP_SELECT_COUNT - 1); + if (pcs > LPSPI_CHIP_SELECT_COUNT - 1) { + LOG_WRN("Peripheral %d select exceeds max %d", pcs, LPSPI_CHIP_SELECT_COUNT - 1); return -EINVAL; } + return 0; +} + +int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg) +{ + const struct spi_mcux_config *config = dev->config; + struct spi_mcux_data *data = dev->data; + struct spi_context *ctx = &data->ctx; + bool already_configured = spi_context_configured(ctx, spi_cfg); + LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); + uint32_t word_size = SPI_WORD_SIZE_GET(spi_cfg->operation); + lpspi_master_config_t master_config; + uint32_t clock_freq; + int ret; + + /* fast path to avoid reconfigure */ + /* TODO: S32K3 errata ERR050456 requiring module reset before every transfer, + * investigate alternative workaround so we don't have this latency for S32. + */ + if (already_configured && !IS_ENABLED(CONFIG_SOC_FAMILY_NXP_S32)) { + return 0; + } + + ret = lpspi_validate_xfer_args(spi_cfg); + if (ret) { + return ret; + } + ret = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clock_freq); if (ret) { return ret; } - if (configured) { + if (already_configured) { /* Setting the baud rate in LPSPI_MasterInit requires module to be disabled. Only * disable if already configured, otherwise the clock is not enabled and the * CR register cannot be written. From 35c38ef2d2d8fb937510de2156825128368931bd Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 18 Feb 2025 10:38:12 -0600 Subject: [PATCH 7/8] spi_nxp_lpspi: Remove SDK items from header file Remove SDK types and defines from header file. And since now the common file is the only consumer of SDK header, move that include there. Also rename the tristate boolean to be more clean about what it does rather than trying to be similar to the SDK config name. Signed-off-by: Declan Snyder --- .../spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c | 5 +++-- .../spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h | 20 ++++++------------- 2 files changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c index 2840b3e454132..890091e992162 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c @@ -8,6 +8,7 @@ LOG_MODULE_REGISTER(spi_mcux_lpspi_common, CONFIG_SPI_LOG_LEVEL); #include "spi_nxp_lpspi_priv.h" +#include #if defined(LPSPI_RSTS) || defined(LPSPI_CLOCKS) static LPSPI_Type *const lpspi_bases[] = LPSPI_BASE_PTRS; @@ -170,8 +171,8 @@ int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cf master_config.pcsActiveHighOrLow = (spi_cfg->operation & SPI_CS_ACTIVE_HIGH) ? kLPSPI_PcsActiveHigh : kLPSPI_PcsActiveLow; master_config.pinCfg = config->data_pin_config; - master_config.dataOutConfig = config->output_config ? kLpspiDataOutTristate : - kLpspiDataOutRetained; + master_config.dataOutConfig = config->tristate_output ? kLpspiDataOutTristate : + kLpspiDataOutRetained; LPSPI_MasterInit(base, &master_config, clock_freq); LPSPI_SetDummyData(base, 0); diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h index 493b147b66841..887cfea641e0c 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "../spi_context.h" @@ -16,8 +17,6 @@ #include #endif -#include - /* If any hardware revisions change this, make it into a DT property. * DONT'T make #ifdefs here by platform. */ @@ -30,10 +29,6 @@ #define DEV_CFG(_dev) ((const struct spi_mcux_config *)(_dev)->config) #define DEV_DATA(_dev) ((struct spi_mcux_data *)(_dev)->data) -/* flag for SDK API for master transfers */ -#define LPSPI_MASTER_XFER_CFG_FLAGS(slave) \ - kLPSPI_MasterPcsContinuous | (slave << LPSPI_MASTER_PCS_SHIFT) - struct spi_mcux_config { DEVICE_MMIO_NAMED_ROM(reg_base); const struct device *clock_dev; @@ -43,8 +38,8 @@ struct spi_mcux_config { uint32_t sck_pcs_delay; uint32_t transfer_delay; const struct pinctrl_dev_config *pincfg; - lpspi_pin_config_t data_pin_config; - bool output_config; + uint8_t data_pin_config; + bool tristate_output; uint8_t tx_fifo_size; uint8_t rx_fifo_size; uint8_t irqn; @@ -58,7 +53,7 @@ struct spi_mcux_data { size_t transfer_len; }; -/* common configure function that verifies spi_cfg validity and set up configuration parameters */ +/* verifies spi_cfg validity and set up configuration of hardware for xfer */ int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg); /* Does these things: @@ -75,9 +70,6 @@ int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg) void lpspi_wait_tx_fifo_empty(const struct device *dev); -/* Argument to MCUX SDK IRQ handler */ -#define LPSPI_IRQ_HANDLE_ARG COND_CODE_1(CONFIG_NXP_LP_FLEXCOMM, (LPSPI_GetInstance(base)), (base)) - #define SPI_MCUX_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n) \ nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), DEVICE_DT_INST_GET(n), \ LP_FLEXCOMM_PERIPH_LPSPI, lpspi_isr); @@ -108,8 +100,8 @@ void lpspi_wait_tx_fifo_empty(const struct device *dev); .transfer_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, transfer_delay), \ DT_INST_PROP(n, transfer_delay)), \ .pincfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n), \ - .data_pin_config = DT_INST_ENUM_IDX(n, data_pin_config), \ - .output_config = DT_INST_PROP(n, tristate_output), \ + .data_pin_config = (uint8_t)DT_INST_ENUM_IDX(n, data_pin_config), \ + .tristate_output = DT_INST_PROP(n, tristate_output), \ .rx_fifo_size = (uint8_t)DT_INST_PROP(n, rx_fifo_size), \ .tx_fifo_size = (uint8_t)DT_INST_PROP(n, tx_fifo_size), \ .irqn = (uint8_t)LPSPI_IRQN(n), \ From 37e45cf692f9b7821f620228df1796e0f304cbb1 Mon Sep 17 00:00:00 2001 From: Declan Snyder Date: Tue, 1 Apr 2025 18:17:11 -0500 Subject: [PATCH 8/8] spi_nxp_lpspi: Remove mcux branding from tokens Since these drivers mainly do not use MCUX except for the configure function (which will soon also be changed), change namespace prefix to lpspi_ instead of spi_mcux_ to avoid confusion. Also improve descriptions of kconfigs to clarify what they are for. Not changing the kconfig names for now since they are user-facing. Signed-off-by: Declan Snyder --- drivers/spi/spi_nxp_lpspi/Kconfig | 22 ++++--- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c | 60 +++++++++---------- .../spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c | 14 ++--- drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c | 54 ++++++++--------- .../spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h | 38 ++++++------ 5 files changed, 98 insertions(+), 90 deletions(-) diff --git a/drivers/spi/spi_nxp_lpspi/Kconfig b/drivers/spi/spi_nxp_lpspi/Kconfig index 8ff926c931bc8..aabb4d51ce7e6 100644 --- a/drivers/spi/spi_nxp_lpspi/Kconfig +++ b/drivers/spi/spi_nxp_lpspi/Kconfig @@ -1,4 +1,4 @@ -# Copyright 2018, 2024 NXP +# Copyright 2018, 2024-2025 NXP # SPDX-License-Identifier: Apache-2.0 config SPI_MCUX_LPSPI @@ -8,24 +8,32 @@ config SPI_MCUX_LPSPI depends on CLOCK_CONTROL select PINCTRL help - Enable support for NXP LPSPI. + Enable driver support for NXP LPSPI. if SPI_MCUX_LPSPI config SPI_MCUX_LPSPI_DMA - bool "MCUX LPSPI SPI DMA Support" + bool "NXP LPSPI DMA-based Driver" default y select DMA depends on $(dt_compat_any_has_prop,$(DT_COMPAT_NXP_LPSPI),dmas) help - Enable the SPI DMA mode for SPI instances - that enable dma channels in their device tree node. + Enable DMA-based transfers for LPSPI peripherals + that have a dmas property specified in their DT node. + The DMA based driver prioritizes bandwidth over latency, due to + DMA being more efficient for larger data transfers, to avoid CPU + having to be utilized to do the work. However, setting up a DMA + transfer is more complicated setup than just starting the transfer + immediately with CPU, so there could be more latency between + the point of requesting a transfer and when it actually starts. config SPI_MCUX_LPSPI_CPU - bool "NXP MCUX LPSPI driver" + bool "NXP LPSPI CPU-based driver" default y depends on $(dt_compat_any_not_has_prop,$(DT_COMPAT_NXP_LPSPI),dmas) || !SPI_MCUX_LPSPI_DMA help - Use the CPU-based LPSPI driver. + Enable "normal" CPU based SPI driver for LPSPI. + This has lower latency than DMA-based driver but over the + longer transfers will likely have less bandwidth and use more CPU time. endif # SPI_MCUX_LPSPI diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c index f5a6c305431f0..629f2c8574263 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi.c @@ -7,7 +7,7 @@ #define DT_DRV_COMPAT nxp_lpspi #include -LOG_MODULE_REGISTER(spi_mcux_lpspi, CONFIG_SPI_LOG_LEVEL); +LOG_MODULE_REGISTER(spi_lpspi, CONFIG_SPI_LOG_LEVEL); #include "spi_nxp_lpspi_priv.h" @@ -30,7 +30,7 @@ static inline uint8_t tx_fifo_cur_len(LPSPI_Type *base) static inline void lpspi_rx_word_write_bytes(const struct device *dev, size_t offset) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; uint8_t num_bytes = MIN(lpspi_data->word_size_bytes, ctx->rx_len); @@ -50,7 +50,7 @@ static inline void lpspi_rx_word_write_bytes(const struct device *dev, size_t of /* Reads a maximum number of words from RX fifo and writes them to the remainder of the RX buf */ static inline size_t lpspi_rx_buf_write_words(const struct device *dev, uint8_t max_read) { - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; size_t buf_len = DIV_ROUND_UP(ctx->rx_len, lpspi_data->word_size_bytes); @@ -69,7 +69,7 @@ static inline size_t lpspi_rx_buf_write_words(const struct device *dev, uint8_t static inline void lpspi_handle_rx_irq(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; uint8_t rx_fsr = rx_fifo_cur_len(base); @@ -98,7 +98,7 @@ static inline void lpspi_handle_rx_irq(const struct device *dev) static inline uint32_t lpspi_next_tx_word(const struct device *dev, int offset) { - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; const uint8_t *byte = ctx->tx_buf + offset; @@ -115,7 +115,7 @@ static inline uint32_t lpspi_next_tx_word(const struct device *dev, int offset) static inline void lpspi_fill_tx_fifo(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; size_t bytes_in_xfer = lpspi_data->fill_len * lpspi_data->word_size_bytes; size_t offset; @@ -130,7 +130,7 @@ static inline void lpspi_fill_tx_fifo(const struct device *dev) static void lpspi_fill_tx_fifo_nop(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; for (int i = 0; i < lpspi_data->fill_len; i++) { @@ -142,8 +142,8 @@ static void lpspi_fill_tx_fifo_nop(const struct device *dev) static void lpspi_next_tx_fill(const struct device *dev) { - const struct spi_mcux_config *config = dev->config; - struct spi_mcux_data *data = dev->data; + const struct lpspi_config *config = dev->config; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; size_t max_chunk; @@ -163,7 +163,7 @@ static void lpspi_next_tx_fill(const struct device *dev) static inline void lpspi_handle_tx_irq(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; @@ -182,8 +182,8 @@ static inline void lpspi_handle_tx_irq(const struct device *dev) static void lpspi_isr(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - const struct spi_mcux_config *config = dev->config; - struct spi_mcux_data *data = dev->data; + const struct lpspi_config *config = dev->config; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; uint32_t status_flags = base->SR; @@ -229,7 +229,7 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg bool asynchronous, spi_callback_t cb, void *userdata) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct lpspi_driver_data *lpspi_data = (struct lpspi_driver_data *)data->driver_data; struct spi_context *ctx = &data->ctx; int ret = 0; @@ -280,7 +280,7 @@ static int transceive(const struct device *dev, const struct spi_config *spi_cfg return ret; } -static int spi_mcux_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, +static int lpspi_transceive_sync(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs) { @@ -288,7 +288,7 @@ static int spi_mcux_transceive_sync(const struct device *dev, const struct spi_c } #ifdef CONFIG_SPI_ASYNC -static int spi_mcux_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, +static int lpspi_transceive_async(const struct device *dev, const struct spi_config *spi_cfg, const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs, spi_callback_t cb, void *userdata) @@ -297,20 +297,20 @@ static int spi_mcux_transceive_async(const struct device *dev, const struct spi_ } #endif /* CONFIG_SPI_ASYNC */ -static DEVICE_API(spi, spi_mcux_driver_api) = { - .transceive = spi_mcux_transceive_sync, +static DEVICE_API(spi, lpspi_driver_api) = { + .transceive = lpspi_transceive_sync, #ifdef CONFIG_SPI_ASYNC - .transceive_async = spi_mcux_transceive_async, + .transceive_async = lpspi_transceive_async, #endif #ifdef CONFIG_SPI_RTIO .iodev_submit = spi_rtio_iodev_default_submit, #endif - .release = spi_mcux_release, + .release = spi_lpspi_release, }; -static int spi_mcux_init(const struct device *dev) +static int lpspi_init(const struct device *dev) { - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; int err = 0; err = spi_nxp_init_common(dev); @@ -325,23 +325,23 @@ static int spi_mcux_init(const struct device *dev) #define LPSPI_INIT(n) \ SPI_NXP_LPSPI_COMMON_INIT(n) \ - SPI_MCUX_LPSPI_CONFIG_INIT(n) \ + SPI_LPSPI_CONFIG_INIT(n) \ \ static struct lpspi_driver_data lpspi_##n##_driver_data; \ \ - static struct spi_mcux_data spi_mcux_data_##n = { \ + static struct lpspi_data lpspi_data_##n = { \ SPI_NXP_LPSPI_COMMON_DATA_INIT(n) \ .driver_data = &lpspi_##n##_driver_data, \ }; \ \ - SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_init, NULL, &spi_mcux_data_##n, \ - &spi_mcux_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ - &spi_mcux_driver_api); + SPI_DEVICE_DT_INST_DEFINE(n, lpspi_init, NULL, &lpspi_data_##n, \ + &lpspi_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &lpspi_driver_api); -#define SPI_MCUX_LPSPI_INIT_IF_DMA(n) IF_DISABLED(SPI_NXP_LPSPI_HAS_DMAS(n), (LPSPI_INIT(n))) +#define SPI_LPSPI_INIT_IF_DMA(n) IF_DISABLED(SPI_NXP_LPSPI_HAS_DMAS(n), (LPSPI_INIT(n))) -#define SPI_MCUX_LPSPI_INIT(n) \ +#define SPI_LPSPI_INIT(n) \ COND_CODE_1(CONFIG_SPI_MCUX_LPSPI_DMA, \ - (SPI_MCUX_LPSPI_INIT_IF_DMA(n)), (LPSPI_INIT(n))) + (SPI_LPSPI_INIT_IF_DMA(n)), (LPSPI_INIT(n))) -DT_INST_FOREACH_STATUS_OKAY(SPI_MCUX_LPSPI_INIT) +DT_INST_FOREACH_STATUS_OKAY(SPI_LPSPI_INIT) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c index 890091e992162..7f65b2c9cd0ea 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_common.c @@ -5,7 +5,7 @@ */ #include -LOG_MODULE_REGISTER(spi_mcux_lpspi_common, CONFIG_SPI_LOG_LEVEL); +LOG_MODULE_REGISTER(spi_lpspi_common, CONFIG_SPI_LOG_LEVEL); #include "spi_nxp_lpspi_priv.h" #include @@ -61,9 +61,9 @@ void lpspi_wait_tx_fifo_empty(const struct device *dev) } } -int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg) +int spi_lpspi_release(const struct device *dev, const struct spi_config *spi_cfg) { - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; spi_context_unlock_unconditionally(&data->ctx); @@ -103,8 +103,8 @@ static inline int lpspi_validate_xfer_args(const struct spi_config *spi_cfg) int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cfg) { - const struct spi_mcux_config *config = dev->config; - struct spi_mcux_data *data = dev->data; + const struct lpspi_config *config = dev->config; + struct lpspi_data *data = dev->data; struct spi_context *ctx = &data->ctx; bool already_configured = spi_context_configured(ctx, spi_cfg); LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); @@ -198,8 +198,8 @@ static void lpspi_module_system_init(LPSPI_Type *base) int spi_nxp_init_common(const struct device *dev) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - const struct spi_mcux_config *config = dev->config; - struct spi_mcux_data *data = dev->data; + const struct lpspi_config *config = dev->config; + struct lpspi_data *data = dev->data; int err = 0; DEVICE_MMIO_NAMED_MAP(dev, reg_base, K_MEM_CACHE_NONE | K_MEM_DIRECT_MAP); diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c index 7b3f34645abd1..061d0bd7dc030 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_dma.c @@ -7,7 +7,7 @@ #define DT_DRV_COMPAT nxp_lpspi #include -LOG_MODULE_REGISTER(spi_mcux_lpspi_dma, CONFIG_SPI_LOG_LEVEL); +LOG_MODULE_REGISTER(spi_lpspi_dma, CONFIG_SPI_LOG_LEVEL); #include #include "spi_nxp_lpspi_priv.h" @@ -30,7 +30,7 @@ struct spi_nxp_dma_data { struct spi_dma_stream dma_tx; }; -static struct dma_block_config *spi_mcux_dma_common_load(struct spi_dma_stream *stream, +static struct dma_block_config *lpspi_dma_common_load(struct spi_dma_stream *stream, const struct device *dev, const uint8_t *buf, size_t len) { @@ -47,13 +47,13 @@ static struct dma_block_config *spi_mcux_dma_common_load(struct spi_dma_stream * return blk_cfg; } -static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len) +static int lpspi_dma_tx_load(const struct device *dev, const uint8_t *buf, size_t len) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; struct spi_dma_stream *stream = &dma_data->dma_tx; - struct dma_block_config *blk_cfg = spi_mcux_dma_common_load(stream, dev, buf, len); + struct dma_block_config *blk_cfg = lpspi_dma_common_load(stream, dev, buf, len); if (buf == NULL) { /* pretend that nop value comes from peripheral so dma doesn't move source */ @@ -69,13 +69,13 @@ static int spi_mcux_dma_tx_load(const struct device *dev, const uint8_t *buf, si return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); } -static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf, size_t len) +static int lpspi_dma_rx_load(const struct device *dev, uint8_t *buf, size_t len) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; struct spi_dma_stream *stream = &dma_data->dma_rx; - struct dma_block_config *blk_cfg = spi_mcux_dma_common_load(stream, dev, buf, len); + struct dma_block_config *blk_cfg = lpspi_dma_common_load(stream, dev, buf, len); if (buf == NULL) { /* pretend it is peripheral xfer so DMA just xfer to dummy buf */ @@ -91,9 +91,9 @@ static int spi_mcux_dma_rx_load(const struct device *dev, uint8_t *buf, size_t l return dma_config(stream->dma_dev, stream->channel, &stream->dma_cfg); } -static inline int spi_mcux_dma_rxtx_load(const struct device *dev) +static inline int lpspi_dma_rxtx_load(const struct device *dev) { - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; struct spi_dma_stream *rx = &dma_data->dma_rx; struct spi_dma_stream *tx = &dma_data->dma_tx; @@ -109,12 +109,12 @@ static inline int spi_mcux_dma_rxtx_load(const struct device *dev) return -ENODATA; } - ret = spi_mcux_dma_tx_load(dev, ctx->tx_buf, next_chunk_size); + ret = lpspi_dma_tx_load(dev, ctx->tx_buf, next_chunk_size); if (ret != 0) { return ret; } - ret = spi_mcux_dma_rx_load(dev, ctx->rx_buf, next_chunk_size); + ret = lpspi_dma_rx_load(dev, ctx->rx_buf, next_chunk_size); if (ret != 0) { return ret; } @@ -127,9 +127,9 @@ static inline int spi_mcux_dma_rxtx_load(const struct device *dev) return dma_start(tx->dma_dev, tx->channel); } -static int spi_mcux_dma_next_fill(const struct device *dev) +static int lpspi_dma_next_fill(const struct device *dev) { - struct spi_mcux_data *data = (struct spi_mcux_data *)dev->data; + struct lpspi_data *data = (struct lpspi_data *)dev->data; struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; struct spi_dma_stream *rx = &dma_data->dma_rx; struct spi_dma_stream *tx = &dma_data->dma_tx; @@ -137,14 +137,14 @@ static int spi_mcux_dma_next_fill(const struct device *dev) rx->chunk_done = false; tx->chunk_done = false; - return spi_mcux_dma_rxtx_load(dev); + return lpspi_dma_rxtx_load(dev); } static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t channel, int status) { const struct device *spi_dev = arg; LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(spi_dev, reg_base); - struct spi_mcux_data *data = (struct spi_mcux_data *)spi_dev->data; + struct lpspi_data *data = (struct lpspi_data *)spi_dev->data; struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; struct spi_dma_stream *rx = &dma_data->dma_rx; struct spi_dma_stream *tx = &dma_data->dma_tx; @@ -190,7 +190,7 @@ static void spi_mcux_dma_callback(const struct device *dev, void *arg, uint32_t goto done; } - status = spi_mcux_dma_next_fill(spi_dev); + status = lpspi_dma_next_fill(spi_dev); if (status) { goto error; } @@ -213,7 +213,7 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi bool asynchronous, spi_callback_t cb, void *userdata) { LPSPI_Type *base = (LPSPI_Type *)DEVICE_MMIO_NAMED_GET(dev, reg_base); - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct spi_context *ctx = &data->ctx; int ret; @@ -226,7 +226,7 @@ static int transceive_dma(const struct device *dev, const struct spi_config *spi spi_context_buffers_setup(ctx, tx_bufs, rx_bufs, 1); - ret = spi_mcux_dma_next_fill(dev); + ret = lpspi_dma_next_fill(dev); if (ret == -ENODATA) { /* No transfer to do? So just exit */ ret = 0; @@ -266,7 +266,7 @@ static int lpspi_dma_dev_ready(const struct device *dma_dev) static int spi_mcux_dma_init(const struct device *dev) { - struct spi_mcux_data *data = dev->data; + struct lpspi_data *data = dev->data; struct spi_nxp_dma_data *dma_data = (struct spi_nxp_dma_data *)data->driver_data; int err = 0; @@ -302,7 +302,7 @@ static int spi_nxp_dma_transceive_async(const struct device *dev, const struct s } #endif /* CONFIG_SPI_ASYNC */ -static DEVICE_API(spi, spi_mcux_driver_api) = { +static DEVICE_API(spi, lpspi_dma_driver_api) = { .transceive = spi_nxp_dma_transceive_sync, #ifdef CONFIG_SPI_ASYNC .transceive_async = spi_nxp_dma_transceive_async, @@ -310,7 +310,7 @@ static DEVICE_API(spi, spi_mcux_driver_api) = { #ifdef CONFIG_SPI_RTIO .iodev_submit = spi_rtio_iodev_default_submit, #endif - .release = spi_mcux_release, + .release = spi_lpspi_release, }; static void lpspi_isr(const struct device *dev) @@ -340,16 +340,16 @@ static void lpspi_isr(const struct device *dev) #define LPSPI_DMA_INIT(n) \ SPI_NXP_LPSPI_COMMON_INIT(n) \ - SPI_MCUX_LPSPI_CONFIG_INIT(n) \ + SPI_LPSPI_CONFIG_INIT(n) \ \ static struct spi_nxp_dma_data lpspi_dma_data##n = {SPI_DMA_CHANNELS(n)}; \ \ - static struct spi_mcux_data spi_mcux_data_##n = {.driver_data = &lpspi_dma_data##n, \ + static struct lpspi_data lpspi_data_##n = {.driver_data = &lpspi_dma_data##n, \ SPI_NXP_LPSPI_COMMON_DATA_INIT(n)}; \ \ - SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_dma_init, NULL, &spi_mcux_data_##n, \ - &spi_mcux_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ - &spi_mcux_driver_api); + SPI_DEVICE_DT_INST_DEFINE(n, spi_mcux_dma_init, NULL, &lpspi_data_##n, \ + &lpspi_config_##n, POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, \ + &lpspi_dma_driver_api); #define SPI_NXP_LPSPI_DMA_INIT(n) IF_ENABLED(SPI_NXP_LPSPI_HAS_DMAS(n), (LPSPI_DMA_INIT(n))) diff --git a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h index 887cfea641e0c..2054000de2e66 100644 --- a/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h +++ b/drivers/spi/spi_nxp_lpspi/spi_nxp_lpspi_priv.h @@ -1,5 +1,5 @@ /* - * Copyright 2018, 2024 NXP + * Copyright 2018, 2024-2025 NXP * * SPDX-License-Identifier: Apache-2.0 */ @@ -26,10 +26,10 @@ #define LPSPI_INTERRUPT_BITS GENMASK(8, 13) /* Required by DEVICE_MMIO_NAMED_* macros */ -#define DEV_CFG(_dev) ((const struct spi_mcux_config *)(_dev)->config) -#define DEV_DATA(_dev) ((struct spi_mcux_data *)(_dev)->data) +#define DEV_CFG(_dev) ((const struct lpspi_config *)(_dev)->config) +#define DEV_DATA(_dev) ((struct lpspi_data *)(_dev)->data) -struct spi_mcux_config { +struct lpspi_config { DEVICE_MMIO_NAMED_ROM(reg_base); const struct device *clock_dev; clock_control_subsys_t clock_subsys; @@ -45,7 +45,7 @@ struct spi_mcux_config { uint8_t irqn; }; -struct spi_mcux_data { +struct lpspi_data { DEVICE_MMIO_NAMED_RAM(reg_base); const struct device *dev; struct spi_context ctx; @@ -66,33 +66,33 @@ int spi_mcux_configure(const struct device *dev, const struct spi_config *spi_cf int spi_nxp_init_common(const struct device *dev); /* common api function for now */ -int spi_mcux_release(const struct device *dev, const struct spi_config *spi_cfg); +int spi_lpspi_release(const struct device *dev, const struct spi_config *spi_cfg); void lpspi_wait_tx_fifo_empty(const struct device *dev); -#define SPI_MCUX_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n) \ +#define SPI_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n) \ nxp_lp_flexcomm_setirqhandler(DEVICE_DT_GET(DT_INST_PARENT(n)), DEVICE_DT_INST_GET(n), \ LP_FLEXCOMM_PERIPH_LPSPI, lpspi_isr); -#define SPI_MCUX_LPSPI_IRQ_FUNC_DISTINCT(n) \ +#define SPI_LPSPI_IRQ_FUNC_DISTINCT(n) \ IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), lpspi_isr, DEVICE_DT_INST_GET(n), \ 0); \ irq_enable(DT_INST_IRQN(n)); -#define SPI_MCUX_LPSPI_IRQ_FUNC(n) COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), \ - nxp_lp_flexcomm), \ - (SPI_MCUX_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n)), \ - (SPI_MCUX_LPSPI_IRQ_FUNC_DISTINCT(n))) +#define SPI_LPSPI_IRQ_FUNC(n) COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), \ + nxp_lp_flexcomm), \ + (SPI_LPSPI_IRQ_FUNC_LP_FLEXCOMM(n)), \ + (SPI_LPSPI_IRQ_FUNC_DISTINCT(n))) #define LPSPI_IRQN(n) COND_CODE_1(DT_NODE_HAS_COMPAT(DT_INST_PARENT(n), nxp_lp_flexcomm), \ (DT_IRQN(DT_INST_PARENT(n))), (DT_INST_IRQN(n))) -#define SPI_MCUX_LPSPI_CONFIG_INIT(n) \ - static const struct spi_mcux_config spi_mcux_config_##n = { \ +#define SPI_LPSPI_CONFIG_INIT(n) \ + static const struct lpspi_config lpspi_config_##n = { \ DEVICE_MMIO_NAMED_ROM_INIT(reg_base, DT_DRV_INST(n)), \ .clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(n)), \ .clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(n, name), \ - .irq_config_func = spi_mcux_config_func_##n, \ + .irq_config_func = lpspi_config_func_##n, \ .pcs_sck_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, pcs_sck_delay), \ DT_INST_PROP(n, pcs_sck_delay)), \ .sck_pcs_delay = UTIL_AND(DT_INST_NODE_HAS_PROP(n, sck_pcs_delay), \ @@ -110,14 +110,14 @@ void lpspi_wait_tx_fifo_empty(const struct device *dev); #define SPI_NXP_LPSPI_COMMON_INIT(n) \ PINCTRL_DT_INST_DEFINE(n); \ \ - static void spi_mcux_config_func_##n(const struct device *dev) \ + static void lpspi_config_func_##n(const struct device *dev) \ { \ - SPI_MCUX_LPSPI_IRQ_FUNC(n) \ + SPI_LPSPI_IRQ_FUNC(n) \ } #define SPI_NXP_LPSPI_COMMON_DATA_INIT(n) \ - SPI_CONTEXT_INIT_LOCK(spi_mcux_data_##n, ctx), \ - SPI_CONTEXT_INIT_SYNC(spi_mcux_data_##n, ctx), \ + SPI_CONTEXT_INIT_LOCK(lpspi_data_##n, ctx), \ + SPI_CONTEXT_INIT_SYNC(lpspi_data_##n, ctx), \ SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(n), ctx) #define SPI_NXP_LPSPI_HAS_DMAS(n) \