Skip to content

Commit 41a6274

Browse files
committed
[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 9a22265 commit 41a6274

File tree

1 file changed

+31
-37
lines changed

1 file changed

+31
-37
lines changed

drivers/spi/spi_nrfx_spim.c

Lines changed: 31 additions & 37 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
@@ -91,13 +92,11 @@ struct spi_nrfx_config {
9192
#endif
9293
uint32_t wake_pin;
9394
nrfx_gpiote_t wake_gpiote;
94-
#ifdef CONFIG_DCACHE
95-
uint32_t mem_attr;
96-
#endif
9795
#ifdef USE_CLOCK_REQUESTS
9896
const struct device *clk_dev;
9997
struct nrf_clock_spec clk_spec;
10098
#endif
99+
void *mem_reg;
101100
};
102101

103102
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context);
@@ -442,11 +441,6 @@ static void transfer_next_chunk(const struct device *dev)
442441
}
443442

444443
memcpy(dev_data->tx_buffer, tx_buf, chunk_len);
445-
#ifdef CONFIG_DCACHE
446-
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
447-
sys_cache_data_flush_range(dev_data->tx_buffer, chunk_len);
448-
}
449-
#endif
450444
tx_buf = dev_data->tx_buffer;
451445
}
452446

@@ -463,10 +457,20 @@ static void transfer_next_chunk(const struct device *dev)
463457

464458
dev_data->chunk_len = chunk_len;
465459

466-
xfer.p_tx_buffer = tx_buf;
467-
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
468-
xfer.p_rx_buffer = rx_buf;
469-
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;
460+
xfer.tx_length = spi_context_tx_buf_on(ctx) ? chunk_len : 0;
461+
xfer.rx_length = spi_context_rx_buf_on(ctx) ? chunk_len : 0;
462+
463+
error = dmm_buffer_out_prepare(dev_config->mem_reg, tx_buf, xfer.tx_length,
464+
(void **)&xfer.p_tx_buffer);
465+
if (error != 0) {
466+
goto transfer_next_chunk_end;
467+
}
468+
469+
error = dmm_buffer_in_prepare(dev_config->mem_reg, rx_buf, xfer.rx_length,
470+
(void **)&xfer.p_rx_buffer);
471+
if (error != 0) {
472+
goto transfer_next_chunk_end;
473+
}
470474

471475
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
472476
if (xfer.rx_length == 1 && xfer.tx_length <= 1) {
@@ -491,16 +495,15 @@ static void transfer_next_chunk(const struct device *dev)
491495
}
492496
}
493497

498+
transfer_next_chunk_end:
494499
finish_transaction(dev, error);
495500
}
496501

497502
static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
498503
{
499504
const struct device *dev = p_context;
500505
struct spi_nrfx_data *dev_data = dev->data;
501-
#ifdef CONFIG_DCACHE
502506
const struct spi_nrfx_config *dev_config = dev->config;
503-
#endif
504507

505508
if (p_event->type == NRFX_SPIM_EVENT_DONE) {
506509
/* Chunk length is set to 0 when a transaction is aborted
@@ -514,15 +517,21 @@ static void event_handler(const nrfx_spim_evt_t *p_event, void *p_context)
514517
#ifdef CONFIG_SOC_NRF52832_ALLOW_SPIM_DESPITE_PAN_58
515518
anomaly_58_workaround_clear(dev_data);
516519
#endif
520+
521+
if (spi_context_tx_buf_on(&dev_data->ctx)) {
522+
dmm_buffer_out_release(dev_config->mem_reg,
523+
(void **)p_event->xfer_desc.p_tx_buffer);
524+
}
525+
526+
if (spi_context_rx_buf_on(&dev_data->ctx)) {
527+
dmm_buffer_in_release(dev_config->mem_reg, dev_data->ctx.rx_buf,
528+
dev_data->chunk_len, p_event->xfer_desc.p_rx_buffer);
529+
}
530+
517531
#ifdef SPI_BUFFER_IN_RAM
518532
if (spi_context_rx_buf_on(&dev_data->ctx) &&
519533
p_event->xfer_desc.p_rx_buffer != NULL &&
520534
p_event->xfer_desc.p_rx_buffer != dev_data->ctx.rx_buf) {
521-
#ifdef CONFIG_DCACHE
522-
if (dev_config->mem_attr & DT_MEM_CACHEABLE) {
523-
sys_cache_data_invd_range(dev_data->rx_buffer, dev_data->chunk_len);
524-
}
525-
#endif
526535
(void)memcpy(dev_data->ctx.rx_buf,
527536
dev_data->rx_buffer,
528537
dev_data->chunk_len);
@@ -799,7 +808,6 @@ static int spi_nrfx_deinit(const struct device *dev)
799808
#define SPIM(idx) DT_NODELABEL(spi##idx)
800809
#define SPIM_PROP(idx, prop) DT_PROP(SPIM(idx), prop)
801810
#define SPIM_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(SPIM(idx), prop)
802-
#define SPIM_MEM_REGION(idx) DT_PHANDLE(SPIM(idx), memory_regions)
803811

804812
#define SPI_NRFX_SPIM_EXTENDED_CONFIG(idx) \
805813
IF_ENABLED(NRFX_SPIM_EXTENDED_ENABLED, \
@@ -809,13 +817,6 @@ static int spi_nrfx_deinit(const struct device *dev)
809817
()) \
810818
))
811819

812-
#define SPIM_GET_MEM_ATTR(idx) \
813-
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
814-
(COND_CODE_1(DT_NODE_HAS_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr), \
815-
(DT_PROP(SPIM_MEM_REGION(idx), zephyr_memory_attr)), \
816-
(0))), \
817-
(0))
818-
819820
/* Fast instances depend on the global HSFLL clock controller (as they need
820821
* to request the highest frequency from it to operate correctly), so they
821822
* must be initialized after that controller driver, hence the default SPI
@@ -841,10 +842,10 @@ static int spi_nrfx_deinit(const struct device *dev)
841842
IF_ENABLED(SPI_BUFFER_IN_RAM, \
842843
(static uint8_t spim_##idx##_tx_buffer \
843844
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
844-
SPIM_MEMORY_SECTION(idx); \
845+
DMM_MEMORY_SECTION(SPIM(idx)); \
845846
static uint8_t spim_##idx##_rx_buffer \
846847
[CONFIG_SPI_NRFX_RAM_BUFFER_SIZE] \
847-
SPIM_MEMORY_SECTION(idx);)) \
848+
DMM_MEMORY_SECTION(SPIM(idx));)) \
848849
static struct spi_nrfx_data spi_##idx##_data = { \
849850
IF_ENABLED(CONFIG_MULTITHREADING, \
850851
(SPI_CONTEXT_INIT_LOCK(spi_##idx##_data, ctx),)) \
@@ -881,15 +882,14 @@ static int spi_nrfx_deinit(const struct device *dev)
881882
.wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPIM(idx), wake_gpios, \
882883
WAKE_PIN_NOT_USED), \
883884
.wake_gpiote = WAKE_GPIOTE_INSTANCE(SPIM(idx)), \
884-
IF_ENABLED(CONFIG_DCACHE, \
885-
(.mem_attr = SPIM_GET_MEM_ATTR(idx),)) \
886885
IF_ENABLED(USE_CLOCK_REQUESTS, \
887886
(.clk_dev = SPIM_REQUESTS_CLOCK(SPIM(idx)) \
888887
? DEVICE_DT_GET(DT_CLOCKS_CTLR(SPIM(idx))) \
889888
: NULL, \
890889
.clk_spec = { \
891890
.frequency = NRF_CLOCK_CONTROL_FREQUENCY_MAX, \
892891
},)) \
892+
.mem_reg = DMM_DEV_TO_REG(SPIM(idx)), \
893893
}; \
894894
BUILD_ASSERT(!SPIM_HAS_PROP(idx, wake_gpios) || \
895895
!(DT_GPIO_FLAGS(SPIM(idx), wake_gpios) & GPIO_ACTIVE_LOW),\
@@ -904,12 +904,6 @@ static int spi_nrfx_deinit(const struct device *dev)
904904
POST_KERNEL, SPIM_INIT_PRIORITY(idx), \
905905
&spi_nrfx_driver_api)
906906

907-
#define SPIM_MEMORY_SECTION(idx) \
908-
COND_CODE_1(SPIM_HAS_PROP(idx, memory_regions), \
909-
(__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
910-
SPIM_MEM_REGION(idx)))))), \
911-
())
912-
913907
#define COND_NRF_SPIM_DEVICE(unused, prefix, i, _) \
914908
IF_ENABLED(CONFIG_HAS_HW_NRF_SPIM##prefix##i, (SPI_NRFX_SPIM_DEFINE(prefix##i);))
915909

0 commit comments

Comments
 (0)