From bd09dbe3300eca302b84a8fe64cb302889089ab2 Mon Sep 17 00:00:00 2001 From: Alexandru Gagniuc Date: Tue, 31 Dec 2013 00:17:19 -0500 Subject: cpu/allwinner/a10: Implement udelay using timer 0 Change-Id: I4825f0d57696cd28751c59ae133b7e3315fb78e5 Signed-off-by: Alexandru Gagniuc Reviewed-on: http://review.coreboot.org/4595 Tested-by: build bot (Jenkins) Reviewed-by: Paul Menzel Reviewed-by: David Hendricks --- src/cpu/allwinner/a10/timer.c | 42 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) (limited to 'src/cpu/allwinner/a10/timer.c') diff --git a/src/cpu/allwinner/a10/timer.c b/src/cpu/allwinner/a10/timer.c index e156398be3..60cc60c4d1 100644 --- a/src/cpu/allwinner/a10/timer.c +++ b/src/cpu/allwinner/a10/timer.c @@ -1,19 +1,55 @@ /* - * Placeholder for code to come(needed to complete build) + * Timer control and delays for Allwinner CPUs * * Copyright (C) 2013 Alexandru Gagniuc * Subject to the GNU GPL v2, or (at your option) any later version. */ +#include "timer.h" + +#include #include #include +struct a1x_timer *const tmr0 = + &((struct a1x_timer_module *)A1X_TIMER_BASE)->timer[0]; + +static inline u32 read_timer(void) +{ + return read32(&tmr0->val); +} + void init_timer(void) { - /* Stub */ + u32 reg32; + /* Load the timer rollover value */ + write32(0xffffffff, &tmr0->interval); + /* Configure the timer to run from 24MHz oscillator, no prescaler */ + reg32 = TIMER_CTRL_PRESC_DIV_EXP(0); + reg32 |= TIMER_CTRL_CLK_SRC_OSC24M; + reg32 |= TIMER_CTRL_RELOAD; + reg32 |= TIMER_CTRL_TMR_EN; + write32(reg32, &tmr0->ctrl); } void udelay(unsigned usec) { - /* Stub */ + u32 curr_tick, last_tick; + s32 ticks_left; + + last_tick = read_timer(); + /* 24 timer ticks per microsecond (24 MHz, divided by 1) */ + ticks_left = usec * 24; + + /* FIXME: Should we consider timer rollover? + * From when we start the timer, we have almost three minutes before it + * rolls over, so we should be long into having booted our payload. + */ + while (ticks_left > 0) { + curr_tick = read_timer(); + /* Timer value decreases with each tick */ + ticks_left -= last_tick - curr_tick; + last_tick = curr_tick; + } + } -- cgit v1.2.3