4949#define  COUNTER_SPAN  (GRTC_SYSCOUNTERL_VALUE_Msk | ((uint64_t)GRTC_SYSCOUNTERH_VALUE_Msk << 32))
5050#define  MAX_ABS_TICKS  (COUNTER_SPAN / CYC_PER_TICK)
5151
52- /* To allow use of CCADD we need to limit max cycles to 31 bits. */ 
53- #define  MAX_REL_CYCLES  BIT_MASK(31)
54- #define  MAX_REL_TICKS  (MAX_REL_CYCLES / CYC_PER_TICK)
52+ #define  MAX_TICKS                                                                                   \
53+ 	(((COUNTER_SPAN / CYC_PER_TICK) > INT_MAX) ? INT_MAX : (COUNTER_SPAN / CYC_PER_TICK))
5554
56- #define  LFCLK_FREQUENCY_HZ  DT_PROP(LFCLK_NODE, clock_frequency )
55+ #define  MAX_CYCLES  (MAX_TICKS * CYC_PER_TICK )
5756
58- /* Threshold used to determine if there is a risk of unexpected GRTC COMPARE event coming 
59-  * from previous CC value. 
60-  */ 
61- #define  LATENCY_THR_TICKS  200
57+ #define  LFCLK_FREQUENCY_HZ  DT_PROP(LFCLK_NODE, clock_frequency)
6258
6359#if  defined(CONFIG_TEST )
6460const  int32_t  z_sys_timer_irq_for_test  =  DT_IRQN (GRTC_NODE );
6561#endif 
6662
6763static  void  sys_clock_timeout_handler (int32_t  id , uint64_t  cc_val , void  * p_context );
6864
65+ static  struct  k_spinlock  lock ;
6966static  uint64_t  last_count ; /* Time (SYSCOUNTER value) @last sys_clock_announce() */ 
70- static  uint32_t  last_elapsed ;
71- static  uint64_t  cc_value ; /* Value that is expected to be in CC register. */ 
72- static  uint64_t  expired_cc ; /* Value that is expected to be in CC register. */ 
7367static  atomic_t  int_mask ;
7468static  uint8_t  ext_channels_allocated ;
7569static  uint64_t  grtc_start_value ;
@@ -152,13 +146,17 @@ static void compare_int_unlock(int32_t chan, bool key)
152146static  void  sys_clock_timeout_handler (int32_t  id , uint64_t  cc_val , void  * p_context )
153147{
154148	ARG_UNUSED (id );
155- 	ARG_UNUSED (cc_val );
156149	ARG_UNUSED (p_context );
157- 	uint32_t  dticks ;
150+ 	uint64_t  dticks ;
151+ 	uint64_t  now  =  counter ();
152+ 
153+ 	if  (unlikely (now  <  cc_val )) {
154+ 		return ;
155+ 	}
158156
159157	dticks  =  counter_sub (cc_val , last_count ) / CYC_PER_TICK ;
160- 	 last_count   +=  ( dticks   *   CYC_PER_TICK ); 
161- 	expired_cc   =   cc_val ;
158+ 
159+ 	last_count   +=   dticks   *   CYC_PER_TICK ;
162160
163161	if  (!IS_ENABLED (CONFIG_TICKLESS_KERNEL )) {
164162		/* protection is not needed because we are in the GRTC interrupt 
@@ -167,7 +165,6 @@ static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_conte
167165		system_timeout_set_abs (last_count  +  CYC_PER_TICK );
168166	}
169167
170- 	last_elapsed  =  0 ;
171168	sys_clock_announce ((int32_t )dticks );
172169}
173170
@@ -371,7 +368,6 @@ uint64_t z_nrf_grtc_timer_startup_value_get(void)
371368int  z_nrf_grtc_wakeup_prepare (uint64_t  wake_time_us )
372369{
373370	nrfx_err_t  err_code ;
374- 	static  struct  k_spinlock  lock ;
375371	static  uint8_t  systemoff_channel ;
376372	uint64_t  now  =  counter ();
377373	nrfx_grtc_sleep_config_t  sleep_cfg ;
@@ -434,12 +430,20 @@ int z_nrf_grtc_wakeup_prepare(uint64_t wake_time_us)
434430
435431uint32_t  sys_clock_cycle_get_32 (void )
436432{
437- 	return  nrf_grtc_sys_counter_low_get (NRF_GRTC );
433+ 	k_spinlock_key_t  key  =  k_spin_lock (& lock );
434+ 	uint32_t  ret  =  (uint32_t )counter ();
435+ 
436+ 	k_spin_unlock (& lock , key );
437+ 	return  ret ;
438438}
439439
440440uint64_t  sys_clock_cycle_get_64 (void )
441441{
442- 	return  counter ();
442+ 	k_spinlock_key_t  key  =  k_spin_lock (& lock );
443+ 	uint64_t  ret  =  counter ();
444+ 
445+ 	k_spin_unlock (& lock , key );
446+ 	return  ret ;
443447}
444448
445449uint32_t  sys_clock_elapsed (void )
@@ -448,9 +452,7 @@ uint32_t sys_clock_elapsed(void)
448452		return  0 ;
449453	}
450454
451- 	last_elapsed  =  (uint32_t )counter_sub (counter (), last_count );
452- 
453- 	return  last_elapsed  / CYC_PER_TICK ;
455+ 	return  (uint32_t )(counter_sub (counter (), last_count ) / CYC_PER_TICK );
454456}
455457
456458static  int  sys_clock_driver_init (void )
@@ -491,10 +493,6 @@ static int sys_clock_driver_init(void)
491493
492494	last_count  =  (counter () / CYC_PER_TICK ) *  CYC_PER_TICK ;
493495	grtc_start_value  =  last_count ;
494- 	expired_cc  =  UINT64_MAX ;
495- 	nrfx_grtc_channel_callback_set (system_clock_channel_data .channel ,
496- 				       sys_clock_timeout_handler , NULL );
497- 
498496	int_mask  =  NRFX_GRTC_CONFIG_ALLOWED_CC_CHANNELS_MASK ;
499497	if  (!IS_ENABLED (CONFIG_TICKLESS_KERNEL )) {
500498		system_timeout_set_relative (CYC_PER_TICK );
@@ -553,48 +551,18 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
553551		return ;
554552	}
555553
556- 	uint32_t  ch  =  system_clock_channel_data .channel ;
557- 
558- 	if  ((cc_value  ==  expired_cc ) &&  (ticks  <  MAX_REL_TICKS )) {
559- 		uint32_t  cyc  =  ticks  *  CYC_PER_TICK ;
560- 
561- 		if  (cyc  ==  0 ) {
562- 			/* GRTC will expire anyway since HW ensures that past value triggers an 
563- 			 * event but we need to ensure to always progress the cc_value as this 
564- 			 * if condition expects that cc_value will change after each call to 
565- 			 * set_timeout function. 
566- 			 */ 
567- 			cyc  =  1 ;
568- 		}
554+ 	ticks  =  (ticks  ==  K_TICKS_FOREVER ) ? MAX_TICKS  : MIN (MAX_TICKS , MAX (ticks , 0 ));
569555
570- 		/* If it's the first timeout setting after previous expiration and timeout 
571- 		 * is short so fast method can be used which utilizes relative CC configuration. 
572- 		 */ 
573- 		cc_value  +=  cyc ;
574- 		nrfx_grtc_syscounter_cc_rel_set (ch , cyc , NRFX_GRTC_CC_RELATIVE_COMPARE );
575- 		return ;
576- 	}
556+ 	uint64_t  delta_time  =  ticks  *  CYC_PER_TICK ;
577557
578- 	uint64_t  cyc  =  (uint64_t )ticks  *  CYC_PER_TICK ;
579- 	bool  safe_setting  =  false;
580- 	int64_t  prev_cc_val  =  cc_value ;
558+ 	uint64_t  target_time  =  counter () +  delta_time ;
581559
582- 	cc_value  =  last_count  +  last_elapsed  +  cyc ;
583- 
584- 	/* In case of timeout abort it may happen that CC is being set to a value 
585- 	 * that later than previous CC. If previous CC value is not far in the 
586- 	 * future, there is a risk that COMPARE event will be triggered for that 
587- 	 * previous CC value. If there is such risk safe procedure must be applied 
588- 	 * which is more time consuming but ensures that there will be no spurious 
589- 	 * event. 
560+ 	/* Rounded down target_time to the tick boundary 
561+ 	 * (but not less than one tick after the last) 
590562	 */ 
591- 	if  (prev_cc_val  <  cc_value ) {
592- 		int64_t  now  =  last_count  +  last_elapsed ;
593- 
594- 		safe_setting  =  (prev_cc_val  -  now ) <  LATENCY_THR_TICKS ;
595- 	}
563+ 	target_time  =  MAX ((target_time  -  last_count )/CYC_PER_TICK , 1 )* CYC_PER_TICK  +  last_count ;
596564
597- 	nrfx_grtc_syscounter_cc_abs_set ( ch ,  cc_value ,  safe_setting );
565+ 	system_timeout_set_abs ( target_time );
598566}
599567
600568#if  defined(CONFIG_NRF_GRTC_TIMER_APP_DEFINED_INIT )
0 commit comments