On my Olimex A10s-Olinuxino Micro, time drifts quite fast (something of the order of a second per minute). The driver is written to use a 32kHz clock. The device tree on both sun4i and sun5i only references the 24MHz clock though. And the A10s and A13 datasheets don't document the settings for using the 32kHz clock. The diff below switches the driver over to the 24MHz clock. This could use some additional testing on other boards, especially those with the A10 SoC such as the original Cubieboard.
Index: arch/armv7/sunxi/sunxireg.h =================================================================== RCS file: /cvs/src/sys/arch/armv7/sunxi/sunxireg.h,v retrieving revision 1.8 diff -u -p -r1.8 sunxireg.h --- arch/armv7/sunxi/sunxireg.h 2 Feb 2016 21:40:47 -0000 1.8 +++ arch/armv7/sunxi/sunxireg.h 9 Oct 2016 16:03:38 -0000 @@ -37,9 +37,9 @@ #define SXICMS4(sc, reg, mask, bits) \ SXIWRITE4((sc), (reg), (SXIREAD4((sc), (reg)) & ~(mask)) | (bits)) -#define TIMER0_FREQUENCY (32768) -#define TIMER1_FREQUENCY (32768) -#define TIMER2_FREQUENCY (32768) +#define TIMER0_FREQUENCY (24000000) +#define TIMER1_FREQUENCY (24000000) +#define TIMER2_FREQUENCY (24000000) #define COUNTER_FREQUENCY (24000000) /* SRAM Controller / System Control */ Index: arch/armv7/sunxi/sxitimer.c =================================================================== RCS file: /cvs/src/sys/arch/armv7/sunxi/sxitimer.c,v retrieving revision 1.6 diff -u -p -r1.6 sxitimer.c --- arch/armv7/sunxi/sxitimer.c 18 Jul 2016 19:22:45 -0000 1.6 +++ arch/armv7/sunxi/sxitimer.c 9 Oct 2016 16:03:45 -0000 @@ -52,13 +52,9 @@ #define CNT64_CLR_EN (1 << 0) /* clear enable */ #define CNT64_RL_EN (1 << 1) /* read latch enable */ -#define LOSC_CTRL 0x100 -#define OSC32K_SRC_SEL (1 << 0) - #define TIMER_ENABLE (1 << 0) #define TIMER_RELOAD (1 << 1) #define TIMER_CLK_SRC_MASK (3 << 2) -#define TIMER_LSOSC (0 << 2) #define TIMER_OSC24M (1 << 2) #define TIMER_PLL6_6 (2 << 2) #define TIMER_PRESC_1 (0 << 4) @@ -132,7 +128,7 @@ void sxitimer_attach(struct device *parent, struct device *self, void *args) { struct armv7_attach_args *aa = args; - uint32_t freq, ival, now, cr; + uint32_t freq, ival, now; int unit = self->dv_unit; if (unit != 0) @@ -151,11 +147,6 @@ sxitimer_attach(struct device *parent, s & CNT64_CLR_EN) continue; - /* setup timers */ - cr = bus_space_read_4(sxitimer_iot, sxitimer_ioh, LOSC_CTRL); - cr |= OSC32K_SRC_SEL; /* ext 32.768KHz OSC src */ - bus_space_write_4(sxitimer_iot, sxitimer_ioh, LOSC_CTRL, cr); - skip_init: /* timers are down-counters, from interval to 0 */ now = 0xffffffff; /* known big value */ @@ -163,8 +154,7 @@ skip_init: /* stop timer, and set clk src */ bus_space_write_4(sxitimer_iot, sxitimer_ioh, - TIMER_CTRL(unit), - freq == 24000000 ? TIMER_OSC24M : TIMER_LSOSC); + TIMER_CTRL(unit), TIMER_OSC24M); switch (unit) { /* XXX more XXXXTIMER magic for less lines? */ case TICKTIMER: @@ -217,7 +207,7 @@ skip_init: void sxitimer_cpu_initclocks(void) { - uint32_t isr, ier; + uint32_t isr, ier, ctrl; /* establish interrupts */ arm_intr_establish(sxitimer_irq[TICKTIMER], IPL_CLOCK, @@ -236,17 +226,23 @@ sxitimer_cpu_initclocks(void) bus_space_write_4(sxitimer_iot, sxitimer_ioh, TIMER_IER, ier); /* enable timers */ + ctrl = bus_space_read_4(sxitimer_iot, sxitimer_ioh, + TIMER_CTRL(CNTRTIMER)); bus_space_write_4(sxitimer_iot, sxitimer_ioh, TIMER_CTRL(CNTRTIMER), - TIMER_ENABLE | TIMER_RELOAD | TIMER_CONTINOUS); + ctrl | TIMER_ENABLE | TIMER_RELOAD | TIMER_CONTINOUS); + ctrl = bus_space_read_4(sxitimer_iot, sxitimer_ioh, + TIMER_CTRL(STATTIMER)); bus_space_write_4(sxitimer_iot, sxitimer_ioh, TIMER_CTRL(STATTIMER), - TIMER_ENABLE | TIMER_RELOAD | TIMER_SINGLESHOT); + ctrl | TIMER_ENABLE | TIMER_RELOAD | TIMER_SINGLESHOT); + ctrl = bus_space_read_4(sxitimer_iot, sxitimer_ioh, + TIMER_CTRL(TICKTIMER)); bus_space_write_4(sxitimer_iot, sxitimer_ioh, TIMER_CTRL(TICKTIMER), - TIMER_ENABLE | TIMER_RELOAD | TIMER_SINGLESHOT); + ctrl | TIMER_ENABLE | TIMER_RELOAD | TIMER_SINGLESHOT); } /*