Skip to content

Commit 79a3323

Browse files
nika-nordicrlubos
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 3688480 commit 79a3323

File tree

1 file changed

+37
-38
lines changed

1 file changed

+37
-38
lines changed

drivers/spi/spi_nrfx_spim.c

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#ifdef CONFIG_SOC_NRF54H20_GPD
1717
#include <nrf/gpd.h>
1818
#endif
19+
#include <dmm.h>
1920
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
2021
#include <nrfx_ppi.h>
2122
#endif
@@ -123,9 +124,6 @@ struct spi_nrfx_config {
123124
#endif
124125
uint32_t wake_pin;
125126
nrfx_gpiote_t wake_gpiote;
126-
#ifdef CONFIG_DCACHE
127-
uint32_t mem_attr;
128-
#endif
129127
#ifdef USE_CLOCK_REQUESTS
130128
const struct device *clk_dev;
131129
struct nrf_clock_spec clk_spec;
@@ -134,6 +132,7 @@ struct spi_nrfx_config {
134132
bool cross_domain;
135133
int8_t default_port;
136134
#endif
135+
void *mem_reg;
137136
};
138137

139138
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);
@@ -504,11 +503,6 @@ static void transfer_next_chunk(const struct device *dev)
504503
}
505504

506505
memcpy(dev_data->tx_buffer, tx_buf, chunk_len);
507-
#ifdef CONFIG_DCACHE
508-
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
509-
sys_cache_data_flush_range(dev_data->tx_buffer, chunk_len);
510-
}
511-
#endif
512506
tx_buf = dev_data->tx_buffer;
513507
}
514508

@@ -525,10 +519,20 @@ static void transfer_next_chunk(const struct device *dev)
525519

526520
dev_data->chunk_len = chunk_len;
527521

528-
xfer.p_tx_buffer = tx_buf;
529-
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
530-
xfer.p_rx_buffer = rx_buf;
531-
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;
522+
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
523+
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;
524+
525+
error = dmm_buffer_out_prepare(dev_config->mem_reg, tx_buf, xfer.tx_length,
526+
(void **)&xfer.p_tx_buffer);
527+
if (error != 0) {
528+
goto out_alloc_failed;
529+
}
530+
531+
error = dmm_buffer_in_prepare(dev_config->mem_reg, rx_buf, xfer.rx_length,
532+
(void **)&xfer.p_rx_buffer);
533+
if (error != 0) {
534+
goto in_alloc_failed;
535+
}
532536

533537
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
534538
if (xfer.rx_length == 1 && xfer.tx_length <= 1) {
@@ -551,18 +555,23 @@ static void transfer_next_chunk(const struct device *dev)
551555
anomaly_58_workaround_clear(dev_data);
552556
#endif
553557
}
558+
559+
/* On nrfx_spim_xfer() error */
560+
dmm_buffer_in_release(dev_config->mem_reg, rx_buf, xfer.rx_length,
561+
(void **)&xfer.p_rx_buffer);
562+
in_alloc_failed:
563+
dmm_buffer_out_release(dev_config->mem_reg, (void **)&xfer.p_tx_buffer);
554564
}
555565

566+
out_alloc_failed:
556567
finish_transaction(dev, error);
557568
}
558569

559570
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
560571
{
561572
const struct device *dev = p_context;
562573
struct spi_nrfx_data *dev_data = dev->data;
563-
#ifdef CONFIG_DCACHE
564574
const struct spi_nrfx_config *dev_config = dev->config;
565-
#endif
566575

567576
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
568577
/* Chunk length is set to 0 when a transaction is aborted
@@ -576,15 +585,21 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
576585
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
577586
anomaly_58_workaround_clear(dev_data);
578587
#endif
588+
589+
if (spi_context_tx_buf_on(&dev_data->ctx)) {
590+
dmm_buffer_out_release(dev_config->mem_reg,
591+
(void **)p_event->xfer_desc.p_tx_buffer);
592+
}
593+
594+
if (spi_context_rx_buf_on(&dev_data->ctx)) {
595+
dmm_buffer_in_release(dev_config->mem_reg, dev_data->ctx.rx_buf,
596+
dev_data->chunk_len, p_event->xfer_desc.p_rx_buffer);
597+
}
598+
579599
#ifdef SPI_BUFFER_IN_RAM
580600
if (spi_context_rx_buf_on(&dev_data->ctx) &&
581601
p_event->xfer_desc.p_rx_buffer != NULL &&
582602
p_event->xfer_desc.p_rx_buffer != dev_data->ctx.rx_buf) {
583-
#ifdef CONFIG_DCACHE
584-
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
585-
sys_cache_data_invd_range(dev_data->rx_buffer, dev_data->chunk_len);
586-
}
587-
#endif
588603
(void)memcpy(dev_data->ctx.rx_buf,
589604
dev_data->rx_buffer,
590605
dev_data->chunk_len);
@@ -878,8 +893,6 @@ static int spi_nrfx_deinit(const struct device *dev)
878893
return 0;
879894
}
880895

881-
#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions)
882-
883896
#define SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \
884897
IF_ENABLED(NRFX_SPIM_EXTENDED_ENABLED, \
885898
(.dcx_pin = NRF_SPIM_PIN_NOT_CONNECTED, \
@@ -888,13 +901,6 @@ static int spi_nrfx_deinit(const struct device *dev)
888901
()) \
889902
))
890903

891-
#define SPIM_GET_MEM_ATTR(idx) \
892-
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
893-
(COND_CODE_1(DT_NODE_HAS_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr), \
894-
(DT_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr)), \
895-
(0))), \
896-
(0))
897-
898904
/* Fast instances depend on the global HSFLL clock controller (as they need
899905
* to request the highest frequency from it to operate correctly), so they
900906
* must be initialized after that controller driver, hence the default SPI
@@ -921,10 +927,10 @@ static int spi_nrfx_deinit(const struct device *dev)
921927
IF_ENABLED(SPI_BUFFER_IN_RAM, \
922928
(static uint8_t spim_##idx##_tx_buffer \
923929
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
924-
SPIM_MEMORY_SECTION(idx); \
930+
DMM_MEMORY_SECTION(SPIM(idx)); \
925931
static uint8_t spim_##idx##_rx_buffer \
926932
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
927-
SPIM_MEMORY_SECTION(idx);)) \
933+
DMM_MEMORY_SECTION(SPIM(idx));)) \
928934
static struct spi_nrfx_data spi_##idx##_data = { \
929935
IF_ENABLED(CONFIG_MULTITHREADING, \
930936
(SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \
@@ -961,8 +967,6 @@ static int spi_nrfx_deinit(const struct device *dev)
961967
.wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \
962968
WAKE_PIN_NOT_USED), \
963969
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
964-
IF_ENABLED(CONFIG_DCACHE, \
965-
(.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \
966970
IF_ENABLED(USE_CLOCK_REQUESTS, \
967971
(.clk_dev = SPIM_REQUESTS_CLOCK(SPIM(idx)) \
968972
? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \
@@ -975,6 +979,7 @@ static int spi_nrfx_deinit(const struct device *dev)
975979
.default_port = \
976980
DT_PROP_OR(DT_PHANDLE(SPIM(idx), \
977981
default_gpio_port), port, -1),)) \
982+
.mem_reg = DMM_DEV_TO_REG(SPIM(idx)), \
978983
}; \
979984
BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
980985
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
@@ -989,12 +994,6 @@ static int spi_nrfx_deinit(const struct device *dev)
989994
POST_KERNEL, SPIM_INIT_PRIORITY(idx), \
990995
&spi_nrfx_driver_api)
991996

992-
#define SPIM_MEMORY_SECTION(idx) \
993-
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
994-
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
995-
SPIM_MEM_REGION(idx)))))), \
996-
())
997-
998997
#define COND_NRF_SPIM_DEVICE(unused, prefix, i, _) \
999998
IF_ENABLED(CONFIG_HAS_HW_NRF_SPIM##prefix##i, (SPI_NRFX_SPIM_DEFINE(prefix##i);))
1000999

0 commit comments

Comments
 (0)