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 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
477541DT_INST_FOREACH_STATUS_OKAY (COUNTER_NRFX_TIMER_DEVICE )
0 commit comments