Skip to content

Commit 4fde4df

Browse files
nordic-krchnordicjm
authored andcommitted
Revert "[nrf fromlist] drivers: timer: nrf_grtc_timer: Optimize to reduce register access"
This reverts commit 6346fbb. Signed-off-by: Krzysztof Chruściński <[email protected]>
1 parent 0638dae commit 4fde4df

File tree

1 file changed

+31
-58
lines changed

1 file changed

+31
-58
lines changed

drivers/timer/nrf_grtc_timer.c

Lines changed: 31 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -49,27 +49,21 @@
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)
6460
const int32_t z_sys_timer_irq_for_test = DT_IRQN(GRTC_NODE);
6561
#endif
6662

6763
static void sys_clock_timeout_handler(int32_t id, uint64_t cc_val, void *p_context);
6864

65+
static struct k_spinlock lock;
6966
static 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. */
7367
static atomic_t int_mask;
7468
static uint8_t ext_channels_allocated;
7569
static uint64_t grtc_start_value;
@@ -152,13 +146,17 @@ static void compare_int_unlock(int32_t chan, bool key)
152146
static 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)
371368
int 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

435431
uint32_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

440440
uint64_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

445449
uint32_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

456458
static 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);
@@ -549,47 +547,22 @@ void sys_clock_set_timeout(int32_t ticks, bool idle)
549547
{
550548
ARG_UNUSED(idle);
551549

552-
if (ticks == 0) {
553-
return;
554-
}
555-
556550
if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) {
557551
return;
558552
}
559553

560-
uint32_t ch = system_clock_channel_data.channel;
554+
ticks = (ticks == K_TICKS_FOREVER) ? MAX_TICKS : MIN(MAX_TICKS, MAX(ticks, 0));
561555

562-
if ((cc_value == expired_cc) && (ticks < MAX_REL_TICKS)) {
563-
uint32_t cyc = ticks * CYC_PER_TICK;
556+
uint64_t delta_time = ticks * CYC_PER_TICK;
564557

565-
/* If it's the first timeout setting after previous expiration and timeout
566-
* is short so fast method can be used which utilizes relative CC configuration.
567-
*/
568-
cc_value += cyc;
569-
nrfx_grtc_syscounter_cc_rel_set(ch, cyc, NRFX_GRTC_CC_RELATIVE_COMPARE);
570-
return;
571-
}
572-
573-
uint64_t cyc = (uint64_t)ticks * CYC_PER_TICK;
574-
bool safe_setting = false;
575-
int64_t prev_cc_val = cc_value;
558+
uint64_t target_time = counter() + delta_time;
576559

577-
cc_value = last_count + last_elapsed + cyc;
578-
579-
/* In case of timeout abort it may happen that CC is being set to a value
580-
* that later than previous CC. If previous CC value is not far in the
581-
* future, there is a risk that COMPARE event will be triggered for that
582-
* previous CC value. If there is such risk safe procedure must be applied
583-
* which is more time consuming but ensures that there will be no spurious
584-
* event.
560+
/* Rounded down target_time to the tick boundary
561+
* (but not less than one tick after the last)
585562
*/
586-
if (prev_cc_val < cc_value) {
587-
int64_t now = last_count + last_elapsed;
588-
589-
safe_setting = (prev_cc_val - now) < LATENCY_THR_TICKS;
590-
}
563+
target_time = MAX((target_time - last_count)/CYC_PER_TICK, 1)*CYC_PER_TICK + last_count;
591564

592-
nrfx_grtc_syscounter_cc_abs_set(ch, cc_value, safe_setting);
565+
system_timeout_set_abs(target_time);
593566
}
594567

595568
#if defined(CONFIG_NRF_GRTC_TIMER_APP_DEFINED_INIT)

0 commit comments

Comments
 (0)