summaryrefslogtreecommitdiff
path: root/cpu/arm1136
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/arm1136')
-rw-r--r--cpu/arm1136/cpu.c2
-rw-r--r--cpu/arm1136/mx31/interrupts.c133
-rw-r--r--cpu/arm1136/mx31/serial.c12
-rw-r--r--cpu/arm1136/omap24xx/interrupts.c18
-rw-r--r--cpu/arm1136/start.S16
5 files changed, 125 insertions, 56 deletions
diff --git a/cpu/arm1136/cpu.c b/cpu/arm1136/cpu.c
index c27f8cd58..04861632e 100644
--- a/cpu/arm1136/cpu.c
+++ b/cpu/arm1136/cpu.c
@@ -89,7 +89,7 @@ int cpu_init (void)
* setup up stacks if necessary
*/
#ifdef CONFIG_USE_IRQ
- IRQ_STACK_START = _armboot_start - CFG_MALLOC_LEN - CFG_GBL_DATA_SIZE - 4;
+ IRQ_STACK_START = _armboot_start - CONFIG_SYS_MALLOC_LEN - CONFIG_SYS_GBL_DATA_SIZE - 4;
FIQ_STACK_START = IRQ_STACK_START - CONFIG_STACKSIZE_IRQ;
#endif
return 0;
diff --git a/cpu/arm1136/mx31/interrupts.c b/cpu/arm1136/mx31/interrupts.c
index 21b77a544..ab7202fef 100644
--- a/cpu/arm1136/mx31/interrupts.c
+++ b/cpu/arm1136/mx31/interrupts.c
@@ -23,45 +23,123 @@
#include <common.h>
#include <asm/arch/mx31-regs.h>
+#include <div64.h>
#define TIMER_BASE 0x53f90000 /* General purpose timer 1 */
/* General purpose timers registers */
-#define GPTCR __REG(TIMER_BASE) /* Control register */
-#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */
-#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */
-#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */
+#define GPTCR __REG(TIMER_BASE) /* Control register */
+#define GPTPR __REG(TIMER_BASE + 0x4) /* Prescaler register */
+#define GPTSR __REG(TIMER_BASE + 0x8) /* Status register */
+#define GPTCNT __REG(TIMER_BASE + 0x24) /* Counter register */
/* General purpose timers bitfields */
-#define GPTCR_SWR (1<<15) /* Software reset */
-#define GPTCR_FRR (1<<9) /* Freerun / restart */
-#define GPTCR_CLKSOURCE_32 (4<<6) /* Clock source */
-#define GPTCR_TEN (1) /* Timer enable */
+#define GPTCR_SWR (1 << 15) /* Software reset */
+#define GPTCR_FRR (1 << 9) /* Freerun / restart */
+#define GPTCR_CLKSOURCE_32 (4 << 6) /* Clock source */
+#define GPTCR_TEN 1 /* Timer enable */
+
+static ulong timestamp;
+static ulong lastinc;
+
+/* "time" is measured in 1 / CONFIG_SYS_HZ seconds, "tick" is internal timer period */
+#ifdef CONFIG_MX31_TIMER_HIGH_PRECISION
+/* ~0.4% error - measured with stop-watch on 100s boot-delay */
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, CONFIG_MX31_CLK32);
+ return tick;
+}
+
+static inline unsigned long long time_to_tick(unsigned long long time)
+{
+ time *= CONFIG_MX31_CLK32;
+ do_div(time, CONFIG_SYS_HZ);
+ return time;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long us)
+{
+ us = us * CONFIG_MX31_CLK32 + 999999;
+ do_div(us, 1000000);
+ return us;
+}
+#else
+/* ~2% error */
+#define TICK_PER_TIME ((CONFIG_MX31_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ)
+#define US_PER_TICK (1000000 / CONFIG_MX31_CLK32)
+
+static inline unsigned long long tick_to_time(unsigned long long tick)
+{
+ do_div(tick, TICK_PER_TIME);
+ return tick;
+}
+
+static inline unsigned long long time_to_tick(unsigned long long time)
+{
+ return time * TICK_PER_TIME;
+}
+
+static inline unsigned long long us_to_tick(unsigned long long us)
+{
+ us += US_PER_TICK - 1;
+ do_div(us, US_PER_TICK);
+ return us;
+}
+#endif
/* nothing really to do with interrupts, just starts up a counter. */
+/* The 32768Hz 32-bit timer overruns in 131072 seconds */
int interrupt_init (void)
{
int i;
/* setup GP Timer 1 */
GPTCR = GPTCR_SWR;
- for ( i=0; i<100; i++) GPTCR = 0; /* We have no udelay by now */
+ for (i = 0; i < 100; i++)
+ GPTCR = 0; /* We have no udelay by now */
GPTPR = 0; /* 32Khz */
- GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; /* Freerun Mode, PERCLK1 input */
+ /* Freerun Mode, PERCLK1 input */
+ GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN;
return 0;
}
void reset_timer_masked (void)
{
- GPTCR = 0;
- GPTCR = GPTCR_CLKSOURCE_32 | GPTCR_TEN; /* Freerun Mode, PERCLK1 input */
+ /* reset time */
+ lastinc = GPTCNT; /* capture current incrementer value time */
+ timestamp = 0; /* start "advancing" time stamp from 0 */
+}
+
+void reset_timer(void)
+{
+ reset_timer_masked();
+}
+
+unsigned long long get_ticks (void)
+{
+ ulong now = GPTCNT; /* current tick value */
+
+ if (now >= lastinc) /* normal mode (non roll) */
+ /* move stamp forward with absolut diff ticks */
+ timestamp += (now - lastinc);
+ else /* we have rollover of incrementer */
+ timestamp += (0xFFFFFFFF - lastinc) + now;
+ lastinc = now;
+ return timestamp;
}
ulong get_timer_masked (void)
{
- ulong val = GPTCNT;
- return val;
+ /*
+ * get_ticks() returns a long long (64 bit), it wraps in
+ * 2^64 / CONFIG_MX31_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~
+ * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in
+ * 5 * 10^6 days - long enough.
+ */
+ return tick_to_time(get_ticks());
}
ulong get_timer (ulong base)
@@ -71,29 +149,20 @@ ulong get_timer (ulong base)
void set_timer (ulong t)
{
+ timestamp = time_to_tick(t);
}
/* delay x useconds AND perserve advance timstamp value */
void udelay (unsigned long usec)
{
- ulong tmo, tmp;
-
- if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
- tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
- tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
- tmo /= 1000; /* finish normalize. */
- } else { /* else small number, don't kill it prior to HZ multiply */
- tmo = usec * CFG_HZ;
- tmo /= (1000*1000);
- }
-
- tmp = get_timer (0); /* get current timestamp */
- if ( (tmo + tmp + 1) < tmp )/* if setting this forward will roll time stamp */
- reset_timer_masked (); /* reset "advancing" timestamp to 0, set lastinc value */
- else
- tmo += tmp; /* else, set advancing stamp wake up time */
- while (get_timer_masked () < tmo)/* loop till event */
- /*NOP*/;
+ unsigned long long tmp;
+ ulong tmo;
+
+ tmo = us_to_tick(usec);
+ tmp = get_ticks() + tmo; /* get current timestamp */
+
+ while (get_ticks() < tmp) /* loop till event */
+ /*NOP*/;
}
void reset_cpu (ulong addr)
diff --git a/cpu/arm1136/mx31/serial.c b/cpu/arm1136/mx31/serial.c
index f49859941..e025e941d 100644
--- a/cpu/arm1136/mx31/serial.c
+++ b/cpu/arm1136/mx31/serial.c
@@ -25,18 +25,18 @@
#define __REG(x) (*((volatile u32 *)(x)))
-#ifdef CFG_MX31_UART1
+#ifdef CONFIG_SYS_MX31_UART1
#define UART_PHYS 0x43f90000
-#elif defined(CFG_MX31_UART2)
+#elif defined(CONFIG_SYS_MX31_UART2)
#define UART_PHYS 0x43f94000
-#elif defined(CFG_MX31_UART3)
+#elif defined(CONFIG_SYS_MX31_UART3)
#define UART_PHYS 0x5000c000
-#elif defined(CFG_MX31_UART4)
+#elif defined(CONFIG_SYS_MX31_UART4)
#define UART_PHYS 0x43fb0000
-#elif defined(CFG_MX31_UART5)
+#elif defined(CONFIG_SYS_MX31_UART5)
#define UART_PHYS 0x43fb4000
#else
-#error "define CFG_MX31_UARTx to use the mx31 UART driver"
+#error "define CONFIG_SYS_MX31_UARTx to use the mx31 UART driver"
#endif
/* Register definitions */
diff --git a/cpu/arm1136/omap24xx/interrupts.c b/cpu/arm1136/omap24xx/interrupts.c
index b9a8b9352..fb02a49be 100644
--- a/cpu/arm1136/omap24xx/interrupts.c
+++ b/cpu/arm1136/omap24xx/interrupts.c
@@ -37,7 +37,7 @@
#define TIMER_LOAD_VAL 0
/* macro to read the 32 bit timer */
-#define READ_TIMER (*((volatile ulong *)(CFG_TIMERBASE+TCRR)))
+#define READ_TIMER (*((volatile ulong *)(CONFIG_SYS_TIMERBASE+TCRR)))
static ulong timestamp;
static ulong lastinc;
@@ -48,9 +48,9 @@ int interrupt_init (void)
int32_t val;
/* Start the counter ticking up */
- *((int32_t *) (CFG_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/
- val = (CFG_PVT << 2) | BIT5 | BIT1 | BIT0; /* mask to enable timer*/
- *((int32_t *) (CFG_TIMERBASE + TCLR)) = val; /* start timer */
+ *((int32_t *) (CONFIG_SYS_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/
+ val = (CONFIG_SYS_PVT << 2) | BIT5 | BIT1 | BIT0; /* mask to enable timer*/
+ *((int32_t *) (CONFIG_SYS_TIMERBASE + TCLR)) = val; /* start timer */
reset_timer_masked(); /* init the timestamp and lastinc value */
@@ -81,10 +81,10 @@ void udelay (unsigned long usec)
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
- tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
} else { /* else small number, don't kill it prior to HZ multiply */
- tmo = usec * CFG_HZ;
+ tmo = usec * CONFIG_SYS_HZ;
tmo /= (1000*1000);
}
@@ -125,10 +125,10 @@ void udelay_masked (unsigned long usec)
if (usec >= 1000) { /* if "big" number, spread normalization to seconds */
tmo = usec / 1000; /* start to normalize for usec to ticks per sec */
- tmo *= CFG_HZ; /* find number of "ticks" to wait to achieve target */
+ tmo *= CONFIG_SYS_HZ; /* find number of "ticks" to wait to achieve target */
tmo /= 1000; /* finish normalize. */
} else { /* else small number, don't kill it prior to HZ multiply */
- tmo = usec * CFG_HZ;
+ tmo = usec * CONFIG_SYS_HZ;
tmo /= (1000*1000);
}
endtime = get_timer_masked () + tmo;
@@ -154,6 +154,6 @@ unsigned long long get_ticks(void)
ulong get_tbclk (void)
{
ulong tbclk;
- tbclk = CFG_HZ;
+ tbclk = CONFIG_SYS_HZ;
return tbclk;
}
diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S
index 51b664d93..e6223388d 100644
--- a/cpu/arm1136/start.S
+++ b/cpu/arm1136/start.S
@@ -178,8 +178,8 @@ stack_setup:
#ifdef CONFIG_ONENAND_IPL
sub sp, r0, #128 /* leave 32 words for abort-stack */
#else
- sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
- sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
+ sub r0, r0, #CONFIG_SYS_MALLOC_LEN /* malloc area */
+ sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
@@ -290,8 +290,8 @@ cpu_init_crit:
stmia sp, {r0 - r12} @ Save user registers (now in svc mode) r0-r12
ldr r2, _armboot_start
- sub r2, r2, #(CFG_MALLOC_LEN)
- sub r2, r2, #(CFG_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
+ sub r2, r2, #(CONFIG_SYS_MALLOC_LEN)
+ sub r2, r2, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ set base 2 words into abort stack
ldmia r2, {r2 - r3} @ get values for "aborted" pc and cpsr (into parm regs)
add r0, sp, #S_FRAME_SIZE @ grab pointer to old stack
@@ -323,8 +323,8 @@ cpu_init_crit:
.macro get_bad_stack
ldr r13, _armboot_start @ setup our mode stack (enter in banked mode)
- sub r13, r13, #(CFG_MALLOC_LEN) @ move past malloc pool
- sub r13, r13, #(CFG_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack
+ sub r13, r13, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
+ sub r13, r13, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move to reserved a couple spots for abort stack
str lr, [r13] @ save caller lr in position 0 of saved stack
mrs lr, spsr @ get the spsr
@@ -341,8 +341,8 @@ cpu_init_crit:
sub r13, r13, #4 @ space on current stack for scratch reg.
str r0, [r13] @ save R0's value.
ldr r0, _armboot_start @ get data regions start
- sub r0, r0, #(CFG_MALLOC_LEN) @ move past malloc pool
- sub r0, r0, #(CFG_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack
+ sub r0, r0, #(CONFIG_SYS_MALLOC_LEN) @ move past malloc pool
+ sub r0, r0, #(CONFIG_SYS_GBL_DATA_SIZE+8) @ move past gbl and a couple spots for abort stack
str lr, [r0] @ save caller lr in position 0 of saved stack
mrs r0, spsr @ get the spsr
str lr, [r0, #4] @ save spsr in position 1 of saved stack