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+
3555struct 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
4265struct 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 DEVICE_API(counter, 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 DEVICE_API(counter, 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 DEVICE_API(counter, 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
477541DT_INST_FOREACH_STATUS_OKAY (COUNTER_NRFX_TIMER_DEVICE )
0 commit comments