Hi,
i had forgotten about this already, but this has existed for a while.
systat does consistently show "66 tick"(around 108 for stattick), while
root@av7marsb:~ # vmstat -i
interrupt total rate
irq32/sximmc0 35222 19
irq55/sxie0 3860 2
irq1/com0 17222 9
irq22/tick 181011 99
irq23/stattick 293512 162
Total 530827 293
how come there is such consistent difference? guessing they must source
time differently, so does either use interface leading to rtc _gettime()
instead of timecounters _get_timecount()?
while trying to fix this(, before remembering about "vmstat -i"), i saw
this sillyness in sxitimer irq handlers, unconditional looping that can
be avoided w/slight reordering, and given how it doesn't support other
clocksources, i think it does make sense to avoid the useless bus_space
branching for TIMER_OSC24M-bit while restarting the timers too.
what i mean with above is, given how there is such _sync "price to pay",
for touching _INTV; timer needs to be stopped, and shouldn't be enabled
until 2*Tcycles has passed. it doesn't make sense to delay disabling
to the end right before it is to be restarted.
-Artturi
diff --git a/sys/arch/armv7/sunxi/sxitimer.c b/sys/arch/armv7/sunxi/sxitimer.c
index 65d455adaeb..8abd2137304 100644
--- a/sys/arch/armv7/sunxi/sxitimer.c
+++ b/sys/arch/armv7/sunxi/sxitimer.c
@@ -71,6 +71,9 @@
#define TIMER_CONTINOUS (0 << 7)
#define TIMER_SINGLESHOT (1 << 7)
+#define TIMER_RESTART (TIMER_ENABLE | TIMER_RELOAD | \
+ TIMER_OSC24M | TIMER_SINGLESHOT)
+
#define TICKTIMER 0
#define STATTIMER 1
#define CNTRTIMER 2
@@ -84,8 +87,8 @@ int sxitimer_statintr(void *);
void sxitimer_cpu_initclocks(void);
void sxitimer_setstatclockrate(int);
uint64_t sxitimer_readcnt64(void);
-uint32_t sxitimer_readcnt32(void);
-void sxitimer_sync(void);
+static inline uint32_t sxitimer_readcnt32(void);
+static inline void sxitimer_sync(uint32_t);
void sxitimer_delay(u_int);
u_int sxitimer_get_timecount(struct timecounter *);
@@ -290,7 +293,6 @@ int
sxitimer_tickintr(void *frame)
{
uint32_t now, nextevent;
- uint32_t val;
int rc = 0;
splassert(IPL_CLOCK);
@@ -299,8 +301,11 @@ sxitimer_tickintr(void *frame)
bus_space_write_4(sxitimer_iot, sxitimer_ioh,
TIMER_ISR, TIMER_IRQ(TICKTIMER));
- now = sxitimer_readcnt32();
+ /* stop/disable for sync */
+ bus_space_write_4(sxitimer_iot, sxitimer_ioh,
+ TIMER_CTRL(TICKTIMER), 0);
+ now = sxitimer_readcnt32();
while ((int32_t)(now - sxitimer_tick_nextevt) < 0) {
sxitimer_tick_nextevt -= sxitimer_tick_tpi;
sxitimer_ticks_err_sum += sxitimer_ticks_err_cnt;
@@ -328,21 +333,13 @@ sxitimer_tickintr(void *frame)
sxitimer_tick_nextevt = now;
}
- val = bus_space_read_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(TICKTIMER));
- bus_space_write_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(TICKTIMER), val & ~TIMER_ENABLE);
-
- sxitimer_sync();
+ sxitimer_sync(now);
bus_space_write_4(sxitimer_iot, sxitimer_ioh,
TIMER_INTV(TICKTIMER), nextevent);
- val = bus_space_read_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(TICKTIMER));
bus_space_write_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(TICKTIMER),
- val | TIMER_ENABLE | TIMER_RELOAD | TIMER_SINGLESHOT);
+ TIMER_CTRL(TICKTIMER), TIMER_RESTART);
return rc;
}
@@ -351,7 +348,6 @@ int
sxitimer_statintr(void *frame)
{
uint32_t now, nextevent, r;
- uint32_t val;
int rc = 0;
splassert(IPL_STATCLOCK);
@@ -360,6 +356,10 @@ sxitimer_statintr(void *frame)
bus_space_write_4(sxitimer_iot, sxitimer_ioh,
TIMER_ISR, TIMER_IRQ(STATTIMER));
+ /* stop/disable for sync */
+ bus_space_write_4(sxitimer_iot, sxitimer_ioh,
+ TIMER_CTRL(STATTIMER), 0);
+
now = sxitimer_readcnt32();
while ((int32_t)(now - sxitimer_stat_nextevt) < 0) {
do {
@@ -386,21 +386,13 @@ sxitimer_statintr(void *frame)
sxitimer_stat_nextevt = now;
}
- val = bus_space_read_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(STATTIMER));
- bus_space_write_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(STATTIMER), val & ~TIMER_ENABLE);
-
- sxitimer_sync();
+ sxitimer_sync(now);
bus_space_write_4(sxitimer_iot, sxitimer_ioh,
TIMER_INTV(STATTIMER), nextevent);
- val = bus_space_read_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(STATTIMER));
bus_space_write_4(sxitimer_iot, sxitimer_ioh,
- TIMER_CTRL(STATTIMER),
- val | TIMER_ENABLE | TIMER_RELOAD | TIMER_SINGLESHOT);
+ TIMER_CTRL(STATTIMER), TIMER_RESTART);
return rc;
}
@@ -434,10 +426,8 @@ sxitimer_readcnt32(void)
}
void
-sxitimer_sync(void)
+sxitimer_sync(uint32_t now)
{
- uint32_t now = sxitimer_readcnt32();
-
while ((now - sxitimer_readcnt32()) < TIMER_SYNC)
CPU_BUSY_CYCLE();
}