Skip to content

Commit 511bca4

Browse files
committed
[nrf fromlist] drivers: counter: nrfx_timer: Add request for global HFSLL
Add requesting for global HFSLL when fast instance TIMER (e.g. TIMER120 in nrf54h20) is used. Upstream PR #: 82103 Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 58ff601 commit 511bca4

File tree

2 files changed

+81
-11
lines changed

2 files changed

+81
-11
lines changed

drivers/counter/Kconfig.nrfx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ config COUNTER_NRF_RTC
99
def_bool y
1010
depends on DT_HAS_NORDIC_NRF_RTC_ENABLED
1111

12+
config COUNTER_NRFX_TIMER_USE_CLOCK_CONTROL
13+
def_bool y
14+
depends on $(dt_nodelabel_enabled,timer120) || \
15+
$(dt_nodelabel_enabled,timer121)
16+
select CLOCK_CONTROL
17+
1218
# Internal flag which detects if PPI wrap feature is enabled for any instance
1319
config COUNTER_RTC_WITH_PPI_WRAP
1420
def_bool $(dt_nodelabel_bool_prop,rtc0,ppi-wrap) || \

drivers/counter/counter_nrfx_timer.c

Lines changed: 75 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66
#include <zephyr/drivers/counter.h>
7+
#include <zephyr/drivers/clock_control/nrf_clock_control.h>
8+
#include <zephyr/devicetree.h>
79
#include <hal/nrf_timer.h>
810
#include <zephyr/sys/atomic.h>
911

@@ -32,11 +34,32 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL);
3234
#define MAYBE_CONST_CONFIG const
3335
#endif
3436

37+
#ifdef CONFIG_SOC_NRF54H20_GPD
38+
#include <nrf/gpd.h>
39+
40+
#define NRF_CLOCKS_INSTANCE_IS_FAST(node) \
41+
COND_CODE_1(DT_NODE_HAS_PROP(node, power_domains), \
42+
(IS_EQ(DT_PHA(node, power_domains, id), NRF_GPD_FAST_ACTIVE1)), \
43+
(0))
44+
45+
/* Macro must resolve to literal 0 or 1 */
46+
#define INSTANCE_IS_FAST(idx) NRF_CLOCKS_INSTANCE_IS_FAST(DT_DRV_INST(idx))
47+
48+
#define INSTANCE_IS_FAST_OR(idx) INSTANCE_IS_FAST(idx) ||
49+
50+
#if (DT_INST_FOREACH_STATUS_OKAY(INSTANCE_IS_FAST_OR) 0)
51+
#define COUNTER_ANY_FAST 1
52+
#endif
53+
#endif
54+
3555
struct counter_nrfx_data {
3656
counter_top_callback_t top_cb;
3757
void *top_user_data;
3858
uint32_t guard_period;
3959
atomic_t cc_int_pending;
60+
#ifdef COUNTER_ANY_FAST
61+
atomic_t active;
62+
#endif
4063
};
4164

4265
struct counter_nrfx_ch_data {
@@ -48,6 +71,10 @@ struct counter_nrfx_config {
4871
struct counter_config_info info;
4972
struct counter_nrfx_ch_data *ch_data;
5073
NRF_TIMER_Type *timer;
74+
#ifdef COUNTER_ANY_FAST
75+
const struct device *clk_dev;
76+
struct nrf_clock_spec clk_spec;
77+
#endif
5178
LOG_INSTANCE_PTR_DECLARE(log);
5279
};
5380

@@ -61,6 +88,18 @@ static int start(const struct device *dev)
6188
{
6289
const struct counter_nrfx_config *config = dev->config;
6390

91+
#ifdef COUNTER_ANY_FAST
92+
struct counter_nrfx_data *data = dev->data;
93+
94+
if (config->clk_dev && atomic_cas(&data->active, 0, 1)) {
95+
int err;
96+
97+
err = nrf_clock_control_request_sync(config->clk_dev, &config->clk_spec, K_FOREVER);
98+
if (err < 0) {
99+
return err;
100+
}
101+
}
102+
#endif
64103
nrf_timer_task_trigger(config->timer, NRF_TIMER_TASK_START);
65104

66105
return 0;
@@ -71,6 +110,18 @@ static int stop(const struct device *dev)
71110
const struct counter_nrfx_config *config = dev->config;
72111

73112
nrf_timer_task_trigger(config->timer, NRF_TIMER_TASK_STOP);
113+
#ifdef COUNTER_ANY_FAST
114+
struct counter_nrfx_data *data = dev->data;
115+
116+
if (config->clk_dev && atomic_cas(&data->active, 1, 0)) {
117+
int err;
118+
119+
err = nrf_clock_control_release(config->clk_dev, &config->clk_spec);
120+
if (err < 0) {
121+
return err;
122+
}
123+
}
124+
#endif
74125

75126
return 0;
76127
}
@@ -403,6 +454,20 @@ static const struct counter_driver_api counter_nrfx_driver_api = {
403454
.set_guard_period = set_guard_period,
404455
};
405456

457+
/* Get initialization level of an instance. Instances that requires clock control
458+
* which is using nrfs (IPC) are initialized later.
459+
*/
460+
#define TIMER_INIT_LEVEL(idx) \
461+
COND_CODE_1(INSTANCE_IS_FAST(idx), (POST_KERNEL), (PRE_KERNEL_1))
462+
463+
/* Get initialization priority of an instance. Instances that requires clock control
464+
* which is using nrfs (IPC) are initialized later.
465+
*/
466+
#define TIMER_INIT_PRIO(idx) \
467+
COND_CODE_1(INSTANCE_IS_FAST(idx), \
468+
(UTIL_INC(CONFIG_CLOCK_CONTROL_NRF2_GLOBAL_HSFLL_INIT_PRIORITY)), \
469+
(CONFIG_COUNTER_INIT_PRIORITY))
470+
406471
/*
407472
* Device instantiation is done with node labels due to HAL API
408473
* requirements. In particular, TIMERx_MAX_SIZE values from HALs
@@ -419,14 +484,6 @@ static const struct counter_driver_api counter_nrfx_driver_api = {
419484
irq_handler, DEVICE_DT_INST_GET(idx), 0)) \
420485
)
421486

422-
#if !defined(CONFIG_SOC_SERIES_BSIM_NRFXX)
423-
#define CHECK_MAX_FREQ(idx) \
424-
BUILD_ASSERT(DT_INST_PROP(idx, max_frequency) == \
425-
NRF_TIMER_BASE_FREQUENCY_GET((NRF_TIMER_Type *)DT_INST_REG_ADDR(idx)))
426-
#else
427-
#define CHECK_MAX_FREQ(idx)
428-
#endif
429-
430487
#define COUNTER_NRFX_TIMER_DEVICE(idx) \
431488
BUILD_ASSERT(DT_INST_PROP(idx, prescaler) <= \
432489
TIMER_PRESCALER_PRESCALER_Msk, \
@@ -456,22 +513,29 @@ static const struct counter_driver_api counter_nrfx_driver_api = {
456513
static MAYBE_CONST_CONFIG struct counter_nrfx_config nrfx_counter_##idx##_config = { \
457514
.info = { \
458515
.max_top_value = (uint32_t)BIT64_MASK(DT_INST_PROP(idx, max_bit_width)),\
459-
.freq = DT_INST_PROP(idx, max_frequency) / \
516+
.freq = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)) / \
460517
BIT(DT_INST_PROP(idx, prescaler)), \
461518
.flags = COUNTER_CONFIG_INFO_COUNT_UP, \
462519
.channels = CC_TO_ID(DT_INST_PROP(idx, cc_num)), \
463520
}, \
464521
.ch_data = counter##idx##_ch_data, \
465522
.timer = (NRF_TIMER_Type *)DT_INST_REG_ADDR(idx), \
523+
IF_ENABLED(INSTANCE_IS_FAST(idx), \
524+
(.clk_dev = DEVICE_DT_GET(DT_CLOCKS_CTLR(DT_DRV_INST(idx))), \
525+
.clk_spec = { \
526+
.frequency = NRF_PERIPH_GET_FREQUENCY(DT_DRV_INST(idx)), \
527+
.accuracy = 0, \
528+
.precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT, \
529+
}, \
530+
)) \
466531
LOG_INSTANCE_PTR_INIT(log, LOG_MODULE_NAME, idx) \
467532
}; \
468-
CHECK_MAX_FREQ(idx); \
469533
DEVICE_DT_INST_DEFINE(idx, \
470534
counter_##idx##_init, \
471535
NULL, \
472536
&counter_##idx##_data, \
473537
&nrfx_counter_##idx##_config.info, \
474-
PRE_KERNEL_1, CONFIG_COUNTER_INIT_PRIORITY, \
538+
TIMER_INIT_LEVEL(idx), TIMER_INIT_PRIO(idx), \
475539
&counter_nrfx_driver_api);
476540

477541
DT_INST_FOREACH_STATUS_OKAY(COUNTER_NRFX_TIMER_DEVICE)

0 commit comments

Comments
 (0)