drivers/timer: it51xxx: Compensate time calculation to reduce drift

The EC timer runs at 9.2 MHz, which leads to a non-integer number of
ticks per microsecond. This causes slight overestimation when delays
are computed using whole ticks (e.g., using 10 ticks for 1 µs).
To address this, the busy wait calculation is adjusted with a
compensation factor to minimize cumulative timing error over time.

Signed-off-by: Tim Lin <tim2.lin@ite.corp-partner.google.com>
This commit is contained in:
Tim Lin 2025-05-29 17:43:37 +08:00 committed by Benjamin Cabé
commit 97cdedec80

View file

@ -126,11 +126,16 @@ static uint32_t read_timer_obser(enum ext_timer_idx timer_idx)
uint32_t obser;
__unused uint8_t etnpsr;
/* Critical section */
unsigned int key = irq_lock();
/* Workaround for observation register latch issue */
obser = sys_read32(timer_base + TIMER_ETNCNTOLR(timer_idx));
etnpsr = sys_read8(timer_base + TIMER_ETNPSR(timer_idx));
obser = sys_read32(timer_base + TIMER_ETNCNTOLR(timer_idx));
irq_unlock(key);
return obser;
}
@ -334,16 +339,24 @@ static int timer_init(enum ext_timer_idx ext_timer, enum ext_clk_src_sel clock_s
void arch_busy_wait(uint32_t usec_to_wait)
{
uint32_t start = read_timer_obser(BUSY_WAIT_H_TIMER);
uint32_t compensated_us;
if (!usec_to_wait) {
return;
}
/* Decrease 1us here to calibrate our access registers latency */
usec_to_wait--;
/*
* The EC runs at 9.2MHz, meaning each tick is approximately 108.6ns.
* The number of ticks per microsecond is calculated as:
* COUNT_1US = EC_CLOCK / USEC_PER_SEC = 9200000 / 1000000 = 9.2
* Since the timer counts down from a preset value to 0, using a preload value of
* 9 actually results in 10 ticks per cycle.
* This overestimates 1us and introduces a small cumulative timing error over time.
* To compensate for this, we scale the requested delay using (1000 / 1086).
*/
compensated_us = usec_to_wait * 1000 / 1086;
for (;;) {
if ((read_timer_obser(BUSY_WAIT_H_TIMER) - start) >= usec_to_wait) {
if ((read_timer_obser(BUSY_WAIT_H_TIMER) - start) >= compensated_us) {
break;
}
}