1515#include <nrfx_timer.h>
1616#include <zephyr/sys/util.h>
1717#include <zephyr/kernel.h>
18+ #include <zephyr/cache.h>
1819#include <soc.h>
20+ #include <dmm.h>
1921#include <helpers/nrfx_gppi.h>
2022#include <zephyr/linker/devicetree_regions.h>
2123#include <zephyr/irq.h>
@@ -28,6 +30,8 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
2830#define UARTE_HAS_PROP (idx , prop ) DT_NODE_HAS_PROP(UARTE(idx), prop)
2931#define UARTE_PROP (idx , prop ) DT_PROP(UARTE(idx), prop)
3032
33+ #define UARTE_IS_CACHEABLE (idx ) DMM_IS_REG_CACHEABLE(DT_PHANDLE(UARTE(idx), memory_regions))
34+
3135/* Execute macro f(x) for all instances. */
3236#define UARTE_FOR_EACH_INSTANCE (f , sep , off_code , ...) \
3337 NRFX_FOREACH_PRESENT(UARTE, f, sep, off_code, __VA_ARGS__)
@@ -88,6 +92,12 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
8892#define UARTE_HAS_FRAME_TIMEOUT 1
8993#endif
9094
95+ #define INSTANCE_NEEDS_CACHE_MGMT (unused , prefix , i , prop ) UARTE_IS_CACHEABLE(prefix##i)
96+
97+ #if UARTE_FOR_EACH_INSTANCE (INSTANCE_NEEDS_CACHE_MGMT , (+ ), (0 ), _ )
98+ #define UARTE_ANY_CACHE 1
99+ #endif
100+
91101/*
92102 * RX timeout is divided into time slabs, this define tells how many divisions
93103 * should be made. More divisions - higher timeout accuracy and processor usage.
@@ -112,6 +122,10 @@ struct uarte_async_tx {
112122
113123struct uarte_async_rx {
114124 struct k_timer timer ;
125+ #ifdef CONFIG_HAS_NORDIC_DMM
126+ uint8_t * usr_buf ;
127+ uint8_t * next_usr_buf ;
128+ #endif
115129 uint8_t * buf ;
116130 size_t buf_len ;
117131 size_t offset ;
@@ -197,6 +211,9 @@ struct uarte_nrfx_data {
197211 */
198212#define UARTE_CFG_FLAG_LOW_POWER BIT(2)
199213
214+ /* If enabled then UARTE peripheral is using memory which is cacheable. */
215+ #define UARTE_CFG_FLAG_CACHEABLE BIT(3)
216+
200217/* Macro for converting numerical baudrate to register value. It is convenient
201218 * to use this approach because for constant input it can calculate nrf setting
202219 * at compile time.
@@ -230,6 +247,9 @@ struct uarte_nrfx_config {
230247 uint32_t flags ;
231248 bool disable_rx ;
232249 const struct pinctrl_dev_config * pcfg ;
250+ #ifdef CONFIG_HAS_NORDIC_DMM
251+ void * mem_reg ;
252+ #endif
233253#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
234254 /* None-zero in case of high speed instances. Baudrate is adjusted by that ratio. */
235255 uint32_t clock_freq ;
@@ -571,6 +591,10 @@ static void tx_start(const struct device *dev, const uint8_t *buf, size_t len)
571591 }
572592#endif
573593
594+ if (IS_ENABLED (UARTE_ANY_CACHE ) && (config -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
595+ sys_cache_data_flush_range ((void * )buf , len );
596+ }
597+
574598 nrf_uarte_tx_buffer_set (uarte , buf , len );
575599 nrf_uarte_event_clear (uarte , NRF_UARTE_EVENT_ENDTX );
576600 nrf_uarte_event_clear (uarte , NRF_UARTE_EVENT_TXSTOPPED );
@@ -877,6 +901,19 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
877901 return - EBUSY ;
878902 }
879903
904+ #ifdef CONFIG_HAS_NORDIC_DMM
905+ uint8_t * dma_buf ;
906+ int ret = 0 ;
907+
908+ ret = dmm_buffer_in_prepare (cfg -> mem_reg , buf , len , (void * * )& dma_buf );
909+ if (ret < 0 ) {
910+ return ret ;
911+ }
912+
913+ async_rx -> usr_buf = buf ;
914+ buf = dma_buf ;
915+ #endif
916+
880917#ifdef CONFIG_UART_NRFX_UARTE_ENHANCED_RX
881918#ifdef UARTE_HAS_FRAME_TIMEOUT
882919 if (timeout != SYS_FOREVER_US ) {
@@ -909,8 +946,18 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
909946 if (async_rx -> flush_cnt ) {
910947 int cpy_len = MIN (len , async_rx -> flush_cnt );
911948
949+ if (IS_ENABLED (UARTE_ANY_CACHE ) &&
950+ (cfg -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
951+ sys_cache_data_invd_range (cfg -> rx_flush_buf , cpy_len );
952+ }
953+
912954 memcpy (buf , cfg -> rx_flush_buf , cpy_len );
913955
956+ if (IS_ENABLED (UARTE_ANY_CACHE ) &&
957+ (cfg -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
958+ sys_cache_data_flush_range (buf , cpy_len );
959+ }
960+
914961 buf += cpy_len ;
915962 len -= cpy_len ;
916963
@@ -921,6 +968,11 @@ static int uarte_nrfx_rx_enable(const struct device *dev, uint8_t *buf,
921968 async_rx -> flush_cnt -= cpy_len ;
922969 memmove (cfg -> rx_flush_buf , & cfg -> rx_flush_buf [cpy_len ],
923970 async_rx -> flush_cnt );
971+ if (IS_ENABLED (UARTE_ANY_CACHE ) &&
972+ (cfg -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
973+ sys_cache_data_flush_range (cfg -> rx_flush_buf ,
974+ async_rx -> flush_cnt );
975+ }
924976 atomic_or (& data -> flags , UARTE_FLAG_TRIG_RXTO );
925977 NRFX_IRQ_PENDING_SET (nrfx_get_irq_number (uarte ));
926978 return 0 ;
@@ -966,6 +1018,17 @@ static int uarte_nrfx_rx_buf_rsp(const struct device *dev, uint8_t *buf,
9661018 if (async_rx -> buf == NULL ) {
9671019 err = - EACCES ;
9681020 } else if (async_rx -> next_buf == NULL ) {
1021+ #ifdef CONFIG_HAS_NORDIC_DMM
1022+ uint8_t * dma_buf ;
1023+ const struct uarte_nrfx_config * config = dev -> config ;
1024+
1025+ err = dmm_buffer_in_prepare (config -> mem_reg , buf , len , (void * * )& dma_buf );
1026+ if (err < 0 ) {
1027+ return err ;
1028+ }
1029+ async_rx -> next_usr_buf = buf ;
1030+ buf = dma_buf ;
1031+ #endif
9691032 async_rx -> next_buf = buf ;
9701033 async_rx -> next_buf_len = len ;
9711034 nrf_uarte_rx_buffer_set (uarte , buf , len );
@@ -1235,6 +1298,15 @@ static void endrx_isr(const struct device *dev)
12351298 */
12361299 const int rx_amount = nrf_uarte_rx_amount_get (uarte ) + async_rx -> flush_cnt ;
12371300
1301+ #ifdef CONFIG_HAS_NORDIC_DMM
1302+ const struct uarte_nrfx_config * config = dev -> config ;
1303+ int err =
1304+ dmm_buffer_in_release (config -> mem_reg , async_rx -> usr_buf , rx_amount , async_rx -> buf );
1305+
1306+ (void )err ;
1307+ __ASSERT_NO_MSG (err == 0 );
1308+ async_rx -> buf = async_rx -> usr_buf ;
1309+ #endif
12381310 async_rx -> flush_cnt = 0 ;
12391311
12401312 /* The 'rx_offset' can be bigger than 'rx_amount', so it the length
@@ -1262,6 +1334,9 @@ static void endrx_isr(const struct device *dev)
12621334 rx_buf_release (dev , async_rx -> buf );
12631335 async_rx -> buf = async_rx -> next_buf ;
12641336 async_rx -> buf_len = async_rx -> next_buf_len ;
1337+ #ifdef CONFIG_HAS_NORDIC_DMM
1338+ async_rx -> usr_buf = async_rx -> next_usr_buf ;
1339+ #endif
12651340 async_rx -> next_buf = NULL ;
12661341 async_rx -> next_buf_len = 0 ;
12671342 async_rx -> offset = 0 ;
@@ -1325,11 +1400,15 @@ static uint8_t rx_flush(const struct device *dev, uint8_t *buf)
13251400 /* Flushing RX fifo requires buffer bigger than 4 bytes to empty fifo*/
13261401 static const uint8_t dirty = 0xAA ;
13271402 NRF_UARTE_Type * uarte = get_uarte_instance (dev );
1403+ const struct uarte_nrfx_config * config = dev -> config ;
13281404 uint32_t prev_rx_amount ;
13291405 uint32_t rx_amount ;
13301406
13311407 if (IS_ENABLED (RX_FLUSH_WORKAROUND )) {
13321408 memset (buf , dirty , UARTE_HW_RX_FIFO_SIZE );
1409+ if (IS_ENABLED (UARTE_ANY_CACHE ) && (config -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
1410+ sys_cache_data_flush_range (buf , UARTE_HW_RX_FIFO_SIZE );
1411+ }
13331412 prev_rx_amount = nrf_uarte_rx_amount_get (uarte );
13341413 } else {
13351414 prev_rx_amount = 0 ;
@@ -1360,6 +1439,10 @@ static uint8_t rx_flush(const struct device *dev, uint8_t *buf)
13601439 return 0 ;
13611440 }
13621441
1442+ if (IS_ENABLED (UARTE_ANY_CACHE ) && (config -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
1443+ sys_cache_data_invd_range (buf , UARTE_HW_RX_FIFO_SIZE );
1444+ }
1445+
13631446 for (int i = 0 ; i < rx_amount ; i ++ ) {
13641447 if (buf [i ] != dirty ) {
13651448 return rx_amount ;
@@ -1379,6 +1462,10 @@ static void rxto_isr(const struct device *dev)
13791462 struct uarte_async_rx * async_rx = & data -> async -> rx ;
13801463
13811464 if (async_rx -> buf ) {
1465+ #ifdef CONFIG_HAS_NORDIC_DMM
1466+ (void )dmm_buffer_in_release (config -> mem_reg , async_rx -> usr_buf , 0 , async_rx -> buf );
1467+ async_rx -> buf = async_rx -> usr_buf ;
1468+ #endif
13821469 rx_buf_release (dev , async_rx -> buf );
13831470 async_rx -> buf = NULL ;
13841471 }
@@ -1598,6 +1685,16 @@ static void uarte_nrfx_isr_async(const void *arg)
15981685 }
15991686
16001687 if (atomic_and (& data -> flags , ~UARTE_FLAG_TRIG_RXTO ) & UARTE_FLAG_TRIG_RXTO ) {
1688+ #ifdef CONFIG_HAS_NORDIC_DMM
1689+ int ret ;
1690+
1691+ ret = dmm_buffer_in_release (config -> mem_reg , async_rx -> usr_buf , async_rx -> buf_len ,
1692+ async_rx -> buf );
1693+
1694+ (void )ret ;
1695+ __ASSERT_NO_MSG (ret == 0 );
1696+ async_rx -> buf = async_rx -> usr_buf ;
1697+ #endif
16011698 notify_uart_rx_rdy (dev , async_rx -> buf_len );
16021699 rx_buf_release (dev , async_rx -> buf );
16031700 async_rx -> buf_len = 0 ;
@@ -1633,6 +1730,10 @@ static int uarte_nrfx_poll_in(const struct device *dev, unsigned char *c)
16331730 return -1 ;
16341731 }
16351732
1733+ if (IS_ENABLED (UARTE_ANY_CACHE ) && (config -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
1734+ sys_cache_data_invd_range (config -> poll_in_byte , 1 );
1735+ }
1736+
16361737 * c = * config -> poll_in_byte ;
16371738
16381739 /* clear the interrupt */
@@ -1727,6 +1828,10 @@ static int uarte_nrfx_fifo_read(const struct device *dev,
17271828 /* Clear the interrupt */
17281829 nrf_uarte_event_clear (uarte , NRF_UARTE_EVENT_ENDRX );
17291830
1831+ if (IS_ENABLED (UARTE_ANY_CACHE ) && (config -> flags & UARTE_CFG_FLAG_CACHEABLE )) {
1832+ sys_cache_data_invd_range (config -> poll_in_byte , 1 );
1833+ }
1834+
17301835 /* Receive a character */
17311836 rx_data [num_rx ++ ] = * config -> poll_in_byte ;
17321837
@@ -2200,12 +2305,12 @@ static int uarte_nrfx_pm_action(const struct device *dev,
22002305 IF_ENABLED(CONFIG_UART_##idx##_ASYNC, ( \
22012306 static uint8_t \
22022307 uarte##idx##_tx_cache[CONFIG_UART_ASYNC_TX_CACHE_SIZE] \
2203- UARTE_MEMORY_SECTION( idx); \
2308+ DMM_MEMORY_SECTION(UARTE( idx) ); \
22042309 static uint8_t uarte##idx##_flush_buf[UARTE_HW_RX_FIFO_SIZE] \
2205- UARTE_MEMORY_SECTION( idx); \
2310+ DMM_MEMORY_SECTION(UARTE( idx) ); \
22062311 struct uarte_async_cb uarte##idx##_async;)) \
2207- static uint8_t uarte##idx##_poll_out_byte UARTE_MEMORY_SECTION( idx); \
2208- static uint8_t uarte##idx##_poll_in_byte UARTE_MEMORY_SECTION( idx); \
2312+ static uint8_t uarte##idx##_poll_out_byte DMM_MEMORY_SECTION(UARTE( idx)); \
2313+ static uint8_t uarte##idx##_poll_in_byte DMM_MEMORY_SECTION(UARTE( idx)); \
22092314 static struct uarte_nrfx_data uarte_##idx##_data = { \
22102315 IF_ENABLED(CONFIG_UART_USE_RUNTIME_CONFIGURE, \
22112316 (.uart_config = UARTE_CONFIG(idx),)) \
@@ -2227,11 +2332,16 @@ static int uarte_nrfx_pm_action(const struct device *dev,
22272332 .hw_config = UARTE_NRF_CONFIG(idx),)) \
22282333 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(UARTE(idx)), \
22292334 .uarte_regs = _CONCAT(NRF_UARTE, idx), \
2335+ IF_ENABLED(CONFIG_HAS_NORDIC_DMM, \
2336+ (.mem_reg = DMM_DEV_TO_REG(UARTE(idx)),)) \
22302337 .flags = \
22312338 (IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT) ? \
22322339 UARTE_CFG_FLAG_PPI_ENDTX : 0) | \
22332340 (IS_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC) ? \
22342341 UARTE_CFG_FLAG_HW_BYTE_COUNTING : 0) | \
2342+ (!IS_ENABLED(CONFIG_HAS_NORDIC_DMM) ? 0 : \
2343+ (UARTE_IS_CACHEABLE(idx) ? \
2344+ UARTE_CFG_FLAG_CACHEABLE : 0)) | \
22352345 USE_LOW_POWER(idx), \
22362346 UARTE_DISABLE_RX_INIT(UARTE(idx)), \
22372347 .poll_out_byte = &uarte##idx##_poll_out_byte, \
@@ -2269,19 +2379,13 @@ static int uarte_nrfx_pm_action(const struct device *dev,
22692379 (static uint8_t uarte##idx##_tx_buffer \
22702380 [MIN(CONFIG_UART_##idx##_NRF_TX_BUFFER_SIZE, \
22712381 BIT_MASK(UARTE##idx##_EASYDMA_MAXCNT_SIZE))] \
2272- UARTE_MEMORY_SECTION( idx); \
2382+ DMM_MEMORY_SECTION(UARTE( idx) ); \
22732383 static struct uarte_nrfx_int_driven \
22742384 uarte##idx##_int_driven = { \
22752385 .tx_buffer = uarte##idx##_tx_buffer, \
22762386 .tx_buff_size = sizeof(uarte##idx##_tx_buffer),\
22772387 };))
22782388
2279- #define UARTE_MEMORY_SECTION (idx ) \
2280- COND_CODE_1(UARTE_HAS_PROP(idx, memory_regions), \
2281- (__attribute__((__section__(LINKER_DT_NODE_REGION_NAME( \
2282- DT_PHANDLE(UARTE(idx), memory_regions)))))), \
2283- ())
2284-
22852389#define COND_UART_NRF_UARTE_DEVICE (unused , prefix , i , _ ) \
22862390 IF_ENABLED(CONFIG_HAS_HW_NRF_UARTE##prefix##i, (UART_NRF_UARTE_DEVICE(prefix##i);))
22872391
0 commit comments