Skip to content

Commit 13f7f6a

Browse files
nika-nordicbjarki-andreasen
authored andcommitted
[nrf fromlist] drivers: spi: nrfx_spim: use dmm
Some nRF SoCs (i.e. nRF54H20) can peform DMA transfers only from specific memory regions - `dmm` facilitates that. Upstream PR #: 93487 Signed-off-by: Nikodem Kastelik <[email protected]>
1 parent a626658 commit 13f7f6a

File tree

1 file changed

+38
-38
lines changed

1 file changed

+38
-38
lines changed

drivers/spi/spi_nrfx_spim.c

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <zephyr/drivers/pinctrl.h>
1414
#include <zephyr/mem_mgmt/mem_attr.h>
1515
#include <soc.h>
16+
#include <dmm.h>
1617
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
1718
#include <nrfx_ppi.h>
1819
#endif
@@ -133,9 +134,6 @@ struct spi_nrfx_config {
133134
#endif
134135
uint32_t wake_pin;
135136
nrfx_gpiote_t wake_gpiote;
136-
#ifdef CONFIG_DCACHE
137-
uint32_t mem_attr;
138-
#endif
139137
#ifdef SPIM_ANY_FAST
140138
const struct device *clk_dev;
141139
struct nrf_clock_spec clk_spec;
@@ -144,6 +142,7 @@ struct spi_nrfx_config {
144142
bool cross_domain;
145143
int8_t default_port;
146144
#endif
145+
void *mem_reg;
147146
};
148147

149148
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);
@@ -514,11 +513,6 @@ static void transfer_next_chunk(const struct device *dev)
514513
}
515514

516515
memcpy(dev_data->tx_buffer, tx_buf, chunk_len);
517-
#ifdef CONFIG_DCACHE
518-
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
519-
sys_cache_data_flush_range(dev_data->tx_buffer, chunk_len);
520-
}
521-
#endif
522516
tx_buf = dev_data->tx_buffer;
523517
}
524518

@@ -535,10 +529,20 @@ static void transfer_next_chunk(const struct device *dev)
535529

536530
dev_data->chunk_len = chunk_len;
537531

538-
xfer.p_tx_buffer = tx_buf;
539-
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
540-
xfer.p_rx_buffer = rx_buf;
541-
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;
532+
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
533+
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;
534+
535+
error = dmm_buffer_out_prepare(dev_config->mem_reg, tx_buf, xfer.tx_length,
536+
(void **)&xfer.p_tx_buffer);
537+
if (error != 0) {
538+
goto out_alloc_failed;
539+
}
540+
541+
error = dmm_buffer_in_prepare(dev_config->mem_reg, rx_buf, xfer.rx_length,
542+
(void **)&xfer.p_rx_buffer);
543+
if (error != 0) {
544+
goto in_alloc_failed;
545+
}
542546

543547
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
544548
if (xfer.rx_length == 1 && xfer.tx_length <= 1) {
@@ -561,18 +565,24 @@ static void transfer_next_chunk(const struct device *dev)
561565
anomaly_58_workaround_clear(dev_data);
562566
#endif
563567
}
568+
569+
/* On nrfx_spim_xfer() error */
570+
dmm_buffer_in_release(dev_config->mem_reg, rx_buf, xfer.rx_length,
571+
(void **)&xfer.p_rx_buffer);
572+
in_alloc_failed:
573+
dmm_buffer_out_release(dev_config->mem_reg, (void **)&xfer.p_tx_buffer);
564574
}
565575

576+
out_alloc_failed:
577+
566578
finish_transaction(dev, error);
567579
}
568580

569581
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
570582
{
571583
const struct device *dev = p_context;
572584
struct spi_nrfx_data *dev_data = dev->data;
573-
#ifdef CONFIG_DCACHE
574585
const struct spi_nrfx_config *dev_config = dev->config;
575-
#endif
576586

577587
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
578588
/* Chunk length is set to 0 when a transaction is aborted
@@ -586,15 +596,21 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
586596
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
587597
anomaly_58_workaround_clear(dev_data);
588598
#endif
599+
600+
if (spi_context_tx_buf_on(&dev_data->ctx)) {
601+
dmm_buffer_out_release(dev_config->mem_reg,
602+
(void **)p_event->xfer_desc.p_tx_buffer);
603+
}
604+
605+
if (spi_context_rx_buf_on(&dev_data->ctx)) {
606+
dmm_buffer_in_release(dev_config->mem_reg, dev_data->ctx.rx_buf,
607+
dev_data->chunk_len, p_event->xfer_desc.p_rx_buffer);
608+
}
609+
589610
#ifdef SPI_BUFFER_IN_RAM
590611
if (spi_context_rx_buf_on(&dev_data->ctx) &&
591612
p_event->xfer_desc.p_rx_buffer != NULL &&
592613
p_event->xfer_desc.p_rx_buffer != dev_data->ctx.rx_buf) {
593-
#ifdef CONFIG_DCACHE
594-
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
595-
sys_cache_data_invd_range(dev_data->rx_buffer, dev_data->chunk_len);
596-
}
597-
#endif
598614
(void)memcpy(dev_data->ctx.rx_buf,
599615
dev_data->rx_buffer,
600616
dev_data->chunk_len);
@@ -882,8 +898,6 @@ static int spi_nrfx_deinit(const struct device *dev)
882898
return 0;
883899
}
884900

885-
#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions)
886-
887901
#define SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \
888902
IF_ENABLED(NRFX_SPIM_EXTENDED_ENABLED, \
889903
(.dcx_pin = NRF_SPIM_PIN_NOT_CONNECTED, \
@@ -892,13 +906,6 @@ static int spi_nrfx_deinit(const struct device *dev)
892906
()) \
893907
))
894908

895-
#define SPIM_GET_MEM_ATTR(idx) \
896-
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
897-
(COND_CODE_1(DT_NODE_HAS_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr), \
898-
(DT_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr)), \
899-
(0))), \
900-
(0))
901-
902909
/* Get initialization priority of an instance. Instances that requires clock control
903910
* which is using nrfs (IPC) are initialized later.
904911
*/
@@ -918,10 +925,10 @@ static int spi_nrfx_deinit(const struct device *dev)
918925
IF_ENABLED(SPI_BUFFER_IN_RAM, \
919926
(static uint8_t spim_##idx##_tx_buffer \
920927
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
921-
SPIM_MEMORY_SECTION(idx); \
928+
DMM_MEMORY_SECTION(SPIM(idx)); \
922929
static uint8_t spim_##idx##_rx_buffer \
923930
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
924-
SPIM_MEMORY_SECTION(idx);)) \
931+
DMM_MEMORY_SECTION(SPIM(idx));)) \
925932
static struct spi_nrfx_data spi_##idx##_data = { \
926933
IF_ENABLED(CONFIG_MULTITHREADING, \
927934
(SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \
@@ -958,8 +965,6 @@ static int spi_nrfx_deinit(const struct device *dev)
958965
.wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \
959966
WAKE_PIN_NOT_USED), \
960967
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
961-
IF_ENABLED(CONFIG_DCACHE, \
962-
(.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \
963968
IF_ENABLED(SPIM_ANY_FAST, \
964969
(.clk_dev = DEVICE_DT_GET_OR_NULL( \
965970
DT_CLOCKS_CTLR(SPIM(idx))), \
@@ -971,6 +976,7 @@ static int spi_nrfx_deinit(const struct device *dev)
971976
.default_port = \
972977
DT_PROP_OR(DT_PHANDLE(SPIM(idx), \
973978
default_gpio_port), port, -1),)) \
979+
.mem_reg = DMM_DEV_TO_REG(SPIM(idx)), \
974980
}; \
975981
BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
976982
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
@@ -985,12 +991,6 @@ static int spi_nrfx_deinit(const struct device *dev)
985991
POST_KERNEL, SPIM_INIT_PRIORITY(idx), \
986992
&spi_nrfx_driver_api)
987993

988-
#define SPIM_MEMORY_SECTION(idx) \
989-
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
990-
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
991-
SPIM_MEM_REGION(idx)))))), \
992-
())
993-
994994
#define COND_NRF_SPIM_DEVICE(unused, prefix, i, _) \
995995
IF_ENABLED(CONFIG_HAS_HW_NRF_SPIM##prefix##i, (SPI_NRFX_SPIM_DEFINE(prefix##i);))
996996

0 commit comments

Comments
 (0)