Skip to content

Commit 1c3b63d

Browse files
committed
[nrf fromlist] drivers: serial: nrfx_uarte: Request hsfll clock for fast instance
Request fast global domain to run at 320 MHz during fast UARTE activity. As request is asynchronous it cannot be called from an ISR. Due to complexity to handle that without device runtime power management a requirement is added so that if fast UARTE is used device runtime PM must be enabled. Clock is request and released in PM resume and suspended actions which in case of fast UARTE are only called from thread context. Upstream PR #: 82103 Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 356c249 commit 1c3b63d

File tree

2 files changed

+69
-20
lines changed

2 files changed

+69
-20
lines changed

drivers/serial/Kconfig.nrfx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,11 @@ rsource "Kconfig.nrfx_uart_instance"
101101
endif
102102

103103
if HAS_HW_NRF_UARTE120
104+
105+
config UART_NRFX_UARTE_USE_CLOCK_CONTROL
106+
def_bool y
107+
select CLOCK_CONTROL
108+
104109
nrfx_uart_num = 120
105110
rsource "Kconfig.nrfx_uart_instance"
106111
endif

drivers/serial/uart_nrfx_uarte.c

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,7 @@
2323
#include <zephyr/linker/devicetree_regions.h>
2424
#include <zephyr/irq.h>
2525
#include <zephyr/logging/log.h>
26-
27-
#ifdef CONFIG_SOC_NRF54H20_GPD
28-
#include <nrf/gpd.h>
29-
#endif
26+
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
3027

3128
LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
3229

@@ -110,18 +107,22 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
110107
#define UARTE_ANY_LOW_POWER 1
111108
#endif
112109

113-
BUILD_ASSERT(NRF_GPD_FAST_ACTIVE1 == 0);
110+
#ifdef CONFIG_SOC_NRF54H20_GPD
111+
#include <nrf/gpd.h>
112+
114113
/* Macro must resolve to literal 0 or 1 */
115-
#define INSTANCE_IS_FAST(unused, prefix, idx, _) \
116-
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \
117-
(COND_CODE_1(UTIL_AND(IS_ENABLED(CONFIG_SOC_NRF54H20_GPD), \
118-
DT_NODE_HAS_PROP(UARTE(idx), power_domains)), \
119-
(COND_CODE_0(DT_PHA(UARTE(idx), power_domains, id), (1), (0))),\
120-
(0))), (0))
114+
#define INSTANCE_IS_FAST(unused, prefix, idx, _) \
115+
COND_CODE_1(DT_NODE_HAS_STATUS_OKAY(UARTE(idx)), \
116+
(COND_CODE_1(DT_NODE_HAS_PROP(UARTE(idx), power_domains), \
117+
(IS_EQ(DT_PHA(UARTE(idx), power_domains, id), NRF_GPD_FAST_ACTIVE1)), \
118+
(0))), (0))
121119

122120
#if UARTE_FOR_EACH_INSTANCE(INSTANCE_IS_FAST, (||), (0))
121+
/* Fast instance requires special PM treatment so device runtime PM must be enabled. */
122+
BUILD_ASSERT(IS_ENABLED(CONFIG_PM_DEVICE_RUNTIME));
123123
#define UARTE_ANY_FAST 1
124124
#endif
125+
#endif
125126

126127
#ifdef UARTE_ANY_CACHE
127128
/* uart120 instance does not retain BAUDRATE register when ENABLE=0. When this instance
@@ -308,6 +309,10 @@ struct uarte_nrfx_config {
308309
#ifdef CONFIG_HAS_NORDIC_DMM
309310
void *mem_reg;
310311
#endif
312+
#ifdef UARTE_ANY_FAST
313+
const struct device *clk_dev;
314+
struct nrf_clock_spec clk_spec;
315+
#endif
311316
#ifdef CONFIG_UART_USE_RUNTIME_CONFIGURE
312317
/* None-zero in case of high speed instances. Baudrate is adjusted by that ratio. */
313318
uint32_t clock_freq;
@@ -619,6 +624,16 @@ static void uarte_periph_enable(const struct device *dev)
619624
struct uarte_nrfx_data *data = dev->data;
620625

621626
(void)data;
627+
#ifdef UARTE_ANY_FAST
628+
if (config->clk_dev) {
629+
int err;
630+
631+
err = nrf_clock_control_request_sync(config->clk_dev, &config->clk_spec, K_FOREVER);
632+
(void)err;
633+
__ASSERT_NO_MSG(err >= 0);
634+
}
635+
#endif
636+
622637
nrf_uarte_enable(uarte);
623638
#ifdef CONFIG_SOC_NRF54H20_GPD
624639
nrf_gpd_retain_pins_set(config->pcfg, false);
@@ -700,7 +715,6 @@ static void tx_start(const struct device *dev, const uint8_t *buf, size_t len)
700715
if (LOW_POWER_ENABLED(config)) {
701716
uarte_enable_locked(dev, UARTE_FLAG_LOW_POWER_TX);
702717
}
703-
704718
nrf_uarte_task_trigger(uarte, NRF_UARTE_TASK_STARTTX);
705719
}
706720

@@ -2204,6 +2218,16 @@ static void uarte_pm_suspend(const struct device *dev)
22042218
struct uarte_nrfx_data *data = dev->data;
22052219

22062220
(void)data;
2221+
#ifdef UARTE_ANY_FAST
2222+
if (cfg->clk_dev) {
2223+
int err;
2224+
2225+
err = nrf_clock_control_release(cfg->clk_dev, &cfg->clk_spec);
2226+
(void)err;
2227+
__ASSERT_NO_MSG(err >= 0);
2228+
}
2229+
#endif
2230+
22072231
#ifdef UARTE_ANY_ASYNC
22082232
if (data->async) {
22092233
/* Entering inactive state requires device to be no
@@ -2387,18 +2411,31 @@ static int uarte_instance_init(const struct device *dev,
23872411
#define UARTE_DISABLE_RX_INIT(node_id) \
23882412
.disable_rx = DT_PROP(node_id, disable_rx)
23892413

2390-
#define UARTE_GET_FREQ(idx) DT_PROP(DT_CLOCKS_CTLR(UARTE(idx)), clock_frequency)
2391-
2392-
#define UARTE_GET_BAUDRATE_DIV(idx) \
2393-
COND_CODE_1(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \
2394-
((UARTE_GET_FREQ(idx) / NRF_UARTE_BASE_FREQUENCY_16MHZ)), (1))
2414+
/* Get frequency of the clock that driver the UARTE peripheral. Clock node can
2415+
* have fixed or variable frequency. For fast UARTE use highest supported frequency.
2416+
*/
2417+
#define UARTE_GET_BAUDRATE_DIV(idx) \
2418+
(NRF_PERIPH_GET_FREQUENCY(UARTE(idx)) / NRF_UARTE_BASE_FREQUENCY_16MHZ)
23952419

23962420
/* When calculating baudrate we need to take into account that high speed instances
23972421
* must have baudrate adjust to the ratio between UARTE clocking frequency and 16 MHz.
23982422
*/
23992423
#define UARTE_GET_BAUDRATE(idx) \
24002424
(NRF_BAUDRATE(UARTE_PROP(idx, current_speed)) / UARTE_GET_BAUDRATE_DIV(idx))
24012425

2426+
/* Get initialization level of an instance. Instances that requires clock control
2427+
* which is using nrfs (IPC) are initialized later.
2428+
*/
2429+
#define UARTE_INIT_LEVEL(idx) \
2430+
COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), (POST_KERNEL), (PRE_KERNEL_1))
2431+
2432+
/* Get initialization priority of an instance. Instances that requires clock control
2433+
* which is using nrfs (IPC) are initialized later.
2434+
*/
2435+
#define UARTE_INIT_PRIO(idx) \
2436+
COND_CODE_1(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \
2437+
(UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \
2438+
(CONFIG_SERIAL_INIT_PRIORITY))
24022439

24032440
/* Macro for setting nRF specific configuration structures. */
24042441
#define UARTE_NRF_CONFIG(idx) { \
@@ -2454,7 +2491,7 @@ static int uarte_instance_init(const struct device *dev,
24542491
static const struct uarte_nrfx_config uarte_##idx##z_config = { \
24552492
COND_CODE_1(CONFIG_UART_USE_RUNTIME_CONFIGURE, \
24562493
(IF_ENABLED(DT_CLOCKS_HAS_IDX(UARTE(idx), 0), \
2457-
(.clock_freq = UARTE_GET_FREQ(idx),))), \
2494+
(.clock_freq = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),))), \
24582495
(IF_ENABLED(UARTE_HAS_FRAME_TIMEOUT, \
24592496
(.baudrate = UARTE_PROP(idx, current_speed),)) \
24602497
.nrf_baudrate = UARTE_GET_BAUDRATE(idx), \
@@ -2481,6 +2518,13 @@ static int uarte_instance_init(const struct device *dev,
24812518
IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \
24822519
(.timer = NRFX_TIMER_INSTANCE( \
24832520
CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \
2521+
IF_ENABLED(INSTANCE_IS_FAST(_, /*empty*/, idx, _), \
2522+
(.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(UARTE(idx))), \
2523+
.clk_spec = { \
2524+
.frequency = NRF_PERIPH_GET_FREQUENCY(UARTE(idx)),\
2525+
.accuracy = 0, \
2526+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT,\
2527+
},)) \
24842528
}; \
24852529
static int uarte_##idx##_init(const struct device *dev) \
24862530
{ \
@@ -2501,8 +2545,8 @@ static int uarte_instance_init(const struct device *dev,
25012545
PM_DEVICE_DT_GET(UARTE(idx)), \
25022546
&uarte_##idx##_data, \
25032547
&uarte_##idx##z_config, \
2504-
PRE_KERNEL_1, \
2505-
CONFIG_SERIAL_INIT_PRIORITY, \
2548+
UARTE_INIT_LEVEL(idx), \
2549+
UARTE_INIT_PRIO(idx), \
25062550
&uart_nrfx_uarte_driver_api)
25072551

25082552
#define UARTE_INT_DRIVEN(idx) \

0 commit comments

Comments
 (0)