@@ -148,6 +148,27 @@ BUILD_ASSERT(IS_ENABLED(CONFIG_CLOCK_CONTROL));
148148 */
149149#define UARTE_ANY_HIGH_SPEED (UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_HIGH_SPEED, (||), (0)))
150150
151+ #define UARTE_PINS_CROSS_DOMAIN (unused , prefix , idx , _ ) \
152+ COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(prefix##idx)), \
153+ (UARTE_PROP(idx, cross_domain_pins_supported)), \
154+ (0))
155+
156+ #if UARTE_FOR_EACH_INSTANCE (UARTE_PINS_CROSS_DOMAIN , (|| ), (0 ))
157+ #include <hal/nrf_gpio.h>
158+ /* Certain UARTE instances support usage of cross domain pins in form of dedicated pins on
159+ * a port different from the default one.
160+ */
161+ #define UARTE_CROSS_DOMAIN_PINS_SUPPORTED 1
162+ #endif
163+
164+ #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED && defined(CONFIG_NRF_SYS_EVENT )
165+ #include <nrf_sys_event.h>
166+ /* To use cross domain pins, constant latency mode needs to be applied, which is
167+ * handled via nrf_sys_event requests.
168+ */
169+ #define UARTE_CROSS_DOMAIN_PINS_HANDLE 1
170+ #endif
171+
151172#ifdef UARTE_ANY_CACHE
152173/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
153174 * is used then baudrate must be set after enabling the peripheral and not before.
@@ -371,6 +392,10 @@ struct uarte_nrfx_config {
371392#endif
372393 uint8_t * poll_out_byte ;
373394 uint8_t * poll_in_byte ;
395+ #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
396+ bool cross_domain ;
397+ int8_t default_port ;
398+ #endif
374399};
375400
376401/* Using Macro instead of static inline function to handle NO_OPTIMIZATIONS case
@@ -444,6 +469,32 @@ static void uarte_disable_locked(const struct device *dev, uint32_t dis_mask)
444469 nrf_uarte_disable (get_uarte_instance (dev ));
445470}
446471
472+ #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
473+ static bool uarte_has_cross_domain_connection (const struct uarte_nrfx_config * config )
474+ {
475+ const struct pinctrl_dev_config * pcfg = config -> pcfg ;
476+ const struct pinctrl_state * state ;
477+ int ret ;
478+
479+ ret = pinctrl_lookup_state (pcfg , PINCTRL_STATE_DEFAULT , & state );
480+ if (ret < 0 ) {
481+ LOG_ERR ("Unable to read pin state" );
482+ return false;
483+ }
484+
485+ for (uint8_t i = 0U ; i < state -> pin_cnt ; i ++ ) {
486+ uint32_t pin = NRF_GET_PIN (state -> pins [i ]);
487+
488+ if ((pin != NRF_PIN_DISCONNECTED ) &&
489+ (nrf_gpio_pin_port_number_extract (& pin ) != config -> default_port )) {
490+ return true;
491+ }
492+ }
493+
494+ return false;
495+ }
496+ #endif
497+
447498#if defined(UARTE_ANY_NONE_ASYNC ) && !defined(CONFIG_UART_NRFX_UARTE_NO_IRQ )
448499/**
449500 * @brief Interrupt service routine.
@@ -727,6 +778,19 @@ static void uarte_periph_enable(const struct device *dev)
727778#ifdef CONFIG_SOC_NRF54H20_GPD
728779 nrf_gpd_retain_pins_set (config -> pcfg , false);
729780#endif
781+ #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
782+ if (config -> cross_domain && uarte_has_cross_domain_connection (config )) {
783+ #if UARTE_CROSS_DOMAIN_PINS_HANDLE
784+ int err ;
785+
786+ err = nrf_sys_event_request_global_constlat ();
787+ (void )err ;
788+ __ASSERT_NO_MSG (err >= 0 );
789+ #else
790+ __ASSERT (false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n" );
791+ #endif
792+ }
793+ #endif
730794#if UARTE_BAUDRATE_RETENTION_WORKAROUND
731795 nrf_uarte_baudrate_set (uarte ,
732796 COND_CODE_1 (CONFIG_UART_USE_RUNTIME_CONFIGURE ,
@@ -2411,6 +2475,19 @@ static void uarte_pm_suspend(const struct device *dev)
24112475#ifdef CONFIG_SOC_NRF54H20_GPD
24122476 nrf_gpd_retain_pins_set (cfg -> pcfg , true);
24132477#endif
2478+ #if UARTE_CROSS_DOMAIN_PINS_SUPPORTED
2479+ if (cfg -> cross_domain && uarte_has_cross_domain_connection (cfg )) {
2480+ #if UARTE_CROSS_DOMAIN_PINS_HANDLE
2481+ int err ;
2482+
2483+ err = nrf_sys_event_release_global_constlat ();
2484+ (void )err ;
2485+ __ASSERT_NO_MSG (err >= 0 );
2486+ #else
2487+ __ASSERT (false, "NRF_SYS_EVENT needs to be enabled to use cross domain pins.\n" );
2488+ #endif
2489+ }
2490+ #endif
24142491
24152492 nrf_uarte_disable (uarte );
24162493
@@ -2698,6 +2775,11 @@ static int uarte_instance_init(const struct device *dev,
26982775 .accuracy = 0, \
26992776 .precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\
27002777 },)) \
2778+ IF_ENABLED(UARTE_PINS_CROSS_DOMAIN(_, /*empty*/ , idx , _), \
2779+ (.cross_domain = true, \
2780+ .default_port = \
2781+ DT_PROP_OR(DT_PHANDLE(UARTE(idx), \
2782+ default_gpio_port), port, -1),)) \
27012783 }; \
27022784 UARTE_DIRECT_ISR_DECLARE(idx) \
27032785 static int uarte_##idx##_init(const struct device *dev) \
0 commit comments