From: Jean-Christophe PLAGNIOL-VILLARD Date: Fri, 15 May 2009 21:47:02 +0000 (+0200) Subject: arm: timer and interrupt init rework X-Git-Tag: v2009.08-rc1~153^2~113 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=b54384e3ba6b5535751f317fcd3940a53eed0d3a;p=u-boot arm: timer and interrupt init rework actually the timer init use the interrupt_init as init callback which make the interrupt and timer implementation difficult to follow so now rename it as int timer_init(void) and use interrupt_init for interrupt btw also remane the corresponding file to the functionnality implemented as ixp arch implement two timer - one based on interrupt - so all the timer related code is moved to timer.c Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- diff --git a/board/armltd/integratorap/integratorap.c b/board/armltd/integratorap/integratorap.c index 9631967b07..5ececd6495 100644 --- a/board/armltd/integratorap/integratorap.c +++ b/board/armltd/integratorap/integratorap.c @@ -540,7 +540,7 @@ static ulong div_timer = 1; /* Divisor to convert timer reading * - the Integrator/AP timer issues an interrupt * each time it reaches zero */ -int interrupt_init (void) +int timer_init (void) { /* Load timer with initial value */ *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0) = TIMER_LOAD_VAL; diff --git a/board/armltd/integratorcp/integratorcp.c b/board/armltd/integratorcp/integratorcp.c index 72629ce2b3..0d3afd8d24 100644 --- a/board/armltd/integratorcp/integratorcp.c +++ b/board/armltd/integratorcp/integratorcp.c @@ -163,7 +163,7 @@ static ulong timestamp; /* U-Boot ticks since startup */ /* starts up a counter * - the Integrator/CP timer can be set up to issue an interrupt */ -int interrupt_init (void) +int timer_init (void) { /* Load timer with initial value */ *(volatile ulong *)(CONFIG_SYS_TIMERBASE + 0) = TIMER_LOAD_VAL; diff --git a/board/atmel/at91cap9adk/at91cap9adk.c b/board/atmel/at91cap9adk/at91cap9adk.c index f52edaaa03..9f73df6903 100644 --- a/board/atmel/at91cap9adk/at91cap9adk.c +++ b/board/atmel/at91cap9adk/at91cap9adk.c @@ -61,7 +61,6 @@ static void at91cap9_slowclock_hw_init(void) if (at91_sys_read(AT91_PMC_VER) == ARCH_ID_AT91CAP9_REVC) { unsigned i, tmp = at91_sys_read(AT91_SCKCR); if ((tmp & AT91CAP9_SCKCR_OSCSEL) == AT91CAP9_SCKCR_OSCSEL_RC) { - extern void timer_init(void); timer_init(); tmp |= AT91CAP9_SCKCR_OSC32EN; at91_sys_write(AT91_SCKCR, tmp); diff --git a/board/davinci/common/misc.h b/board/davinci/common/misc.h index 4a57dbb89b..5d29784403 100644 --- a/board/davinci/common/misc.h +++ b/board/davinci/common/misc.h @@ -22,7 +22,6 @@ #ifndef __MISC_H #define __MISC_H -extern void timer_init(void); extern int eth_hw_init(void); void dv_display_clk_infos(void); diff --git a/board/m501sk/m501sk.c b/board/m501sk/m501sk.c index dc5b786c00..1e6a605672 100644 --- a/board/m501sk/m501sk.c +++ b/board/m501sk/m501sk.c @@ -127,7 +127,7 @@ int board_init(void) m501sk_gpio_init(); /* Do interrupt init here, because flash needs timers */ - interrupt_init(); + timer_init(); flash_init(); return 0; diff --git a/board/netstar/netstar.c b/board/netstar/netstar.c index ee4f2cdca7..ffd60bfae0 100644 --- a/board/netstar/netstar.c +++ b/board/netstar/netstar.c @@ -48,7 +48,7 @@ int dram_init(void) /* Take the Ethernet controller out of reset and wait * for the EEPROM load to complete. */ *((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) |= 0x80; - udelay(10); /* doesn't work before interrupt_init call */ + udelay(10); /* doesn't work before timer_init call */ *((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) &= ~0x80; udelay(500); diff --git a/board/voiceblue/voiceblue.c b/board/voiceblue/voiceblue.c index c8dde3651e..59b3310ae8 100644 --- a/board/voiceblue/voiceblue.c +++ b/board/voiceblue/voiceblue.c @@ -43,7 +43,7 @@ int dram_init(void) /* Take the Ethernet controller out of reset and wait * for the EEPROM load to complete. */ *((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) |= 0x80; - udelay(10); /* doesn't work before interrupt_init call */ + udelay(10); /* doesn't work before timer_init call */ *((volatile unsigned short *) GPIO_DATA_OUTPUT_REG) &= ~0x80; udelay(500); diff --git a/cpu/arm1136/mx31/Makefile b/cpu/arm1136/mx31/Makefile index 0e06f0a2b2..1e49e8d80f 100644 --- a/cpu/arm1136/mx31/Makefile +++ b/cpu/arm1136/mx31/Makefile @@ -25,7 +25,8 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).a -COBJS = interrupts.o generic.o +COBJS += generic.o +COBJS += timer.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/arm1136/mx31/interrupts.c b/cpu/arm1136/mx31/interrupts.c deleted file mode 100644 index ab7202fef2..0000000000 --- a/cpu/arm1136/mx31/interrupts.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#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 */ - -/* 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 */ - -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 */ - GPTPR = 0; /* 32Khz */ - /* Freerun Mode, PERCLK1 input */ - GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; - - return 0; -} - -void reset_timer_masked (void) -{ - /* 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) -{ - /* - * 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) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = time_to_tick(t); -} - -/* delay x useconds AND perserve advance timstamp value */ -void udelay (unsigned long usec) -{ - 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) -{ - __REG16(WDOG_BASE) = 4; -} diff --git a/cpu/arm1136/mx31/timer.c b/cpu/arm1136/mx31/timer.c new file mode 100644 index 0000000000..29b484e448 --- /dev/null +++ b/cpu/arm1136/mx31/timer.c @@ -0,0 +1,170 @@ +/* + * (C) Copyright 2007 + * Sascha Hauer, Pengutronix + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#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 */ + +/* 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 */ + +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 + +/* The 32768Hz 32-bit timer overruns in 131072 seconds */ +int timer_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 */ + GPTPR = 0; /* 32Khz */ + /* Freerun Mode, PERCLK1 input */ + GPTCR |= GPTCR_CLKSOURCE_32 | GPTCR_TEN; + + return 0; +} + +void reset_timer_masked (void) +{ + /* 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) +{ + /* + * 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) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = time_to_tick(t); +} + +/* delay x useconds AND perserve advance timstamp value */ +void udelay (unsigned long usec) +{ + 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) +{ + __REG16(WDOG_BASE) = 4; +} diff --git a/cpu/arm1136/omap24xx/Makefile b/cpu/arm1136/omap24xx/Makefile index f9afed72f6..2a79d9bbba 100644 --- a/cpu/arm1136/omap24xx/Makefile +++ b/cpu/arm1136/omap24xx/Makefile @@ -25,9 +25,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).a -COBJS = interrupts.o SOBJS = start.o +COBJS = timer.o + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/arm1136/omap24xx/interrupts.c b/cpu/arm1136/omap24xx/interrupts.c deleted file mode 100644 index a0c535dae8..0000000000 --- a/cpu/arm1136/omap24xx/interrupts.c +++ /dev/null @@ -1,159 +0,0 @@ -/* - * (C) Copyright 2004 - * Texas Instruments - * Richard Woodruff - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#define TIMER_LOAD_VAL 0 - -/* macro to read the 32 bit timer */ -#define READ_TIMER (*((volatile ulong *)(CONFIG_SYS_TIMERBASE+TCRR))) - -static ulong timestamp; -static ulong lastinc; - -/* nothing really to do with interrupts, just starts up a counter. */ -int interrupt_init (void) -{ - int32_t val; - - /* Start the counter ticking up */ - *((int32_t *) (CONFIG_SYS_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/ - val = (CONFIG_SYS_PTV << 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 */ - - return(0); -} -/* - * timer without interrupts - */ -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = 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 *= 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 * CONFIG_SYS_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*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastinc = READ_TIMER; /* capture current incrementer value time */ - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; /* current tick value */ - - if (now >= lastinc) /* normal mode (non roll) */ - timestamp += (now - lastinc); /* move stamp fordward with absoulte diff ticks */ - else /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - lastinc = now; - return timestamp; -} - -/* waits specified delay value and resets timestamp */ -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ - tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ - 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 * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/arm1136/omap24xx/timer.c b/cpu/arm1136/omap24xx/timer.c new file mode 100644 index 0000000000..8dd8d7b008 --- /dev/null +++ b/cpu/arm1136/omap24xx/timer.c @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2004 + * Texas Instruments + * Richard Woodruff + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#define TIMER_LOAD_VAL 0 + +/* macro to read the 32 bit timer */ +#define READ_TIMER (*((volatile ulong *)(CONFIG_SYS_TIMERBASE+TCRR))) + +static ulong timestamp; +static ulong lastinc; + +int timer_init (void) +{ + int32_t val; + + /* Start the counter ticking up */ + *((int32_t *) (CONFIG_SYS_TIMERBASE + TLDR)) = TIMER_LOAD_VAL; /* reload value on overflow*/ + val = (CONFIG_SYS_PTV << 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 */ + + return(0); +} +/* + * timer without interrupts + */ +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = 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 *= 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 * CONFIG_SYS_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*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastinc = READ_TIMER; /* capture current incrementer value time */ + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (now >= lastinc) /* normal mode (non roll) */ + timestamp += (now - lastinc); /* move stamp fordward with absoulte diff ticks */ + else /* we have rollover of incrementer */ + timestamp += (0xFFFFFFFF - lastinc) + now; + lastinc = now; + return timestamp; +} + +/* waits specified delay value and resets timestamp */ +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { /* if "big" number, spread normalization to seconds */ + tmo = usec / 1000; /* start to normalize for usec to ticks per sec */ + 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 * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/cpu/arm1176/s3c64xx/Makefile b/cpu/arm1176/s3c64xx/Makefile index fa4ee3f24e..4656d9a877 100644 --- a/cpu/arm1176/s3c64xx/Makefile +++ b/cpu/arm1176/s3c64xx/Makefile @@ -28,8 +28,8 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).a -COBJS-y = interrupts.o COBJS-$(CONFIG_S3C6400) += cpu_init.o speed.o +COBJS-y += timer.o OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y)) diff --git a/cpu/arm1176/s3c64xx/interrupts.c b/cpu/arm1176/s3c64xx/interrupts.c deleted file mode 100644 index 7bb98486c5..0000000000 --- a/cpu/arm1176/s3c64xx/interrupts.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * (C) Copyright 2008 - * Guennadi Liakhovetki, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -static ulong timer_load_val; - -#define PRESCALER 167 - -static s3c64xx_timers *s3c64xx_get_base_timers(void) -{ - return (s3c64xx_timers *)ELFIN_TIMER_BASE; -} - -/* macro to read the 16 bit timer */ -static inline ulong read_timer(void) -{ - s3c64xx_timers *const timers = s3c64xx_get_base_timers(); - - return timers->TCNTO4; -} - -/* Internal tick units */ -/* Last decremneter snapshot */ -static unsigned long lastdec; -/* Monotonic incrementing timer */ -static unsigned long long timestamp; - -int interrupt_init(void) -{ - s3c64xx_timers *const timers = s3c64xx_get_base_timers(); - - /* use PWM Timer 4 because it has no output */ - /* - * We use the following scheme for the timer: - * Prescaler is hard fixed at 167, divider at 1/4. - * This gives at PCLK frequency 66MHz approx. 10us ticks - * The timer is set to wrap after 100s, at 66MHz this obviously - * happens after 10,000,000 ticks. A long variable can thus - * keep values up to 40,000s, i.e., 11 hours. This should be - * enough for most uses:-) Possible optimizations: select a - * binary-friendly frequency, e.g., 1ms / 128. Also calculate - * the prescaler automatically for other PCLK frequencies. - */ - timers->TCFG0 = PRESCALER << 8; - if (timer_load_val == 0) { - timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */ - timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000; - } - - /* load value for 10 ms timeout */ - lastdec = timers->TCNTB4 = timer_load_val; - /* auto load, manual update of Timer 4 */ - timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | - TCON_4_UPDATE; - - /* auto load, start Timer 4 */ - timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON; - timestamp = 0; - - return 0; -} - -/* - * timer without interrupts - */ - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - ulong now = read_timer(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + timer_load_val - now; - } - lastdec = now; - - return timestamp; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - /* We overrun in 100s */ - return (ulong)(timer_load_val / 100); -} - -void reset_timer_masked(void) -{ - /* reset time */ - lastdec = read_timer(); - timestamp = 0; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer_masked(void) -{ - unsigned long long res = get_ticks(); - do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ))); - return res; -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ)); -} - -void udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = (usec + 9) / 10; - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp)/* loop till event */ - /*NOP*/; -} diff --git a/cpu/arm1176/s3c64xx/timer.c b/cpu/arm1176/s3c64xx/timer.c new file mode 100644 index 0000000000..22a5b77701 --- /dev/null +++ b/cpu/arm1176/s3c64xx/timer.c @@ -0,0 +1,177 @@ +/* + * (C) Copyright 2003 + * Texas Instruments + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002-2004 + * Gary Jennejohn, DENX Software Engineering, + * + * (C) Copyright 2004 + * Philippe Robin, ARM Ltd. + * + * (C) Copyright 2008 + * Guennadi Liakhovetki, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +static ulong timer_load_val; + +#define PRESCALER 167 + +static s3c64xx_timers *s3c64xx_get_base_timers(void) +{ + return (s3c64xx_timers *)ELFIN_TIMER_BASE; +} + +/* macro to read the 16 bit timer */ +static inline ulong read_timer(void) +{ + s3c64xx_timers *const timers = s3c64xx_get_base_timers(); + + return timers->TCNTO4; +} + +/* Internal tick units */ +/* Last decremneter snapshot */ +static unsigned long lastdec; +/* Monotonic incrementing timer */ +static unsigned long long timestamp; + +int timer_init(void) +{ + s3c64xx_timers *const timers = s3c64xx_get_base_timers(); + + /* use PWM Timer 4 because it has no output */ + /* + * We use the following scheme for the timer: + * Prescaler is hard fixed at 167, divider at 1/4. + * This gives at PCLK frequency 66MHz approx. 10us ticks + * The timer is set to wrap after 100s, at 66MHz this obviously + * happens after 10,000,000 ticks. A long variable can thus + * keep values up to 40,000s, i.e., 11 hours. This should be + * enough for most uses:-) Possible optimizations: select a + * binary-friendly frequency, e.g., 1ms / 128. Also calculate + * the prescaler automatically for other PCLK frequencies. + */ + timers->TCFG0 = PRESCALER << 8; + if (timer_load_val == 0) { + timer_load_val = get_PCLK() / PRESCALER * (100 / 4); /* 100s */ + timers->TCFG1 = (timers->TCFG1 & ~0xf0000) | 0x20000; + } + + /* load value for 10 ms timeout */ + lastdec = timers->TCNTB4 = timer_load_val; + /* auto load, manual update of Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | + TCON_4_UPDATE; + + /* auto load, start Timer 4 */ + timers->TCON = (timers->TCON & ~0x00700000) | TCON_4_AUTO | COUNT_4_ON; + timestamp = 0; + + return 0; +} + +/* + * timer without interrupts + */ + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + ulong now = read_timer(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + timer_load_val - now; + } + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + /* We overrun in 100s */ + return (ulong)(timer_load_val / 100); +} + +void reset_timer_masked(void) +{ + /* reset time */ + lastdec = read_timer(); + timestamp = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer_masked(void) +{ + unsigned long long res = get_ticks(); + do_div (res, (timer_load_val / (100 * CONFIG_SYS_HZ))); + return res; +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t * (timer_load_val / (100 * CONFIG_SYS_HZ)); +} + +void udelay(unsigned long usec) +{ + unsigned long long tmp; + ulong tmo; + + tmo = (usec + 9) / 10; + tmp = get_ticks() + tmo; /* get current timestamp */ + + while (get_ticks() < tmp)/* loop till event */ + /*NOP*/; +} diff --git a/cpu/arm720t/interrupts.c b/cpu/arm720t/interrupts.c index 39ed345bb7..ff21314d8e 100644 --- a/cpu/arm720t/interrupts.c +++ b/cpu/arm720t/interrupts.c @@ -110,9 +110,34 @@ static void timer_isr( void *data) { static ulong timestamp; static ulong lastdec; +#if defined(CONFIG_USE_IRQ) && defined(CONFIG_S3C4510B) int interrupt_init (void) { + int i; + + /* install default interrupt handlers */ + for ( i = 0; i < N_IRQS; i++) { + IRQ_HANDLER[i].m_data = (void *)i; + IRQ_HANDLER[i].m_func = default_isr; + } + + /* configure interrupts for IRQ mode */ + PUT_REG( REG_INTMODE, 0x0); + /* clear any pending interrupts */ + PUT_REG( REG_INTPEND, 0x1FFFFF); + + lastdec = 0; + + /* install interrupt handler for timer */ + IRQ_HANDLER[INT_TIMER0].m_data = (void *)×tamp; + IRQ_HANDLER[INT_TIMER0].m_func = timer_isr; + + return 0; +} +#endif +int timer_init (void) +{ #if defined(CONFIG_NETARM) /* disable all interrupts */ IRQEN = 0; @@ -137,25 +162,6 @@ int interrupt_init (void) /* set timer 1 counter */ lastdec = IO_TC1D = TIMER_LOAD_VAL; #elif defined(CONFIG_S3C4510B) - int i; - - /* install default interrupt handlers */ - for ( i = 0; i < N_IRQS; i++) { - IRQ_HANDLER[i].m_data = (void *)i; - IRQ_HANDLER[i].m_func = default_isr; - } - - /* configure interrupts for IRQ mode */ - PUT_REG( REG_INTMODE, 0x0); - /* clear any pending interrupts */ - PUT_REG( REG_INTPEND, 0x1FFFFF); - - lastdec = 0; - - /* install interrupt handler for timer */ - IRQ_HANDLER[INT_TIMER0].m_data = (void *)×tamp; - IRQ_HANDLER[INT_TIMER0].m_func = timer_isr; - /* configure free running timer 0 */ PUT_REG( REG_TMOD, 0x0); /* Stop timer 0 */ @@ -187,7 +193,7 @@ int interrupt_init (void) PUT32(T0TCR, 1); /* enable timer0 */ #else -#error No interrupt_init() defined for this CPU type +#error No timer_init() defined for this CPU type #endif timestamp = 0; diff --git a/cpu/arm920t/at91rm9200/Makefile b/cpu/arm920t/at91rm9200/Makefile index 161ca9492f..73aeeac39d 100644 --- a/cpu/arm920t/at91rm9200/Makefile +++ b/cpu/arm920t/at91rm9200/Makefile @@ -31,10 +31,10 @@ COBJS += bcm5221.o COBJS += dm9161.o COBJS += ether.o COBJS += i2c.o -COBJS += interrupts.o COBJS += lxt972.o COBJS += reset.o COBJS += spi.o +COBJS += timer.o COBJS += usb.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff --git a/cpu/arm920t/at91rm9200/interrupts.c b/cpu/arm920t/at91rm9200/interrupts.c deleted file mode 100644 index 4c38a9a0c8..0000000000 --- a/cpu/arm920t/at91rm9200/interrupts.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * (C) Copyright 2002 - * Lineo, Inc. - * Bernhard Kuhn - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -/*#include */ -#include -/*#include */ - -/* the number of clocks per CONFIG_SYS_HZ */ -#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) - -/* macro to read the 16 bit timer */ -#define READ_TIMER (tmr->TC_CV & 0x0000ffff) -AT91PS_TC tmr; - -static ulong timestamp; -static ulong lastinc; - -int interrupt_init (void) -{ - tmr = AT91C_BASE_TC0; - - /* enables TC1.0 clock */ - *AT91C_PMC_PCER = 1 << AT91C_ID_TC0; /* enable clock */ - - *AT91C_TCB0_BCR = 0; - *AT91C_TCB0_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE; - tmr->TC_CCR = AT91C_TC_CLKDIS; -#define AT91C_TC_CMR_CPCTRG (1 << 14) - /* set to MCLK/2 and restart the timer when the vlaue in TC_RC is reached */ - tmr->TC_CMR = AT91C_TC_TIMER_DIV1_CLOCK | AT91C_TC_CMR_CPCTRG; - - tmr->TC_IDR = ~0ul; - tmr->TC_RC = TIMER_LOAD_VAL; - lastinc = 0; - tmr->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN; - timestamp = 0; - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -void udelay (unsigned long usec) -{ - udelay_masked(usec); -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastinc = READ_TIMER; - timestamp = 0; -} - -ulong get_timer_raw (void) -{ - ulong now = READ_TIMER; - - if (now >= lastinc) { - /* normal mode */ - timestamp += now - lastinc; - } else { - /* we have an overflow ... */ - timestamp += now + TIMER_LOAD_VAL - lastinc; - } - lastinc = now; - - return timestamp; -} - -ulong get_timer_masked (void) -{ - return get_timer_raw()/TIMER_LOAD_VAL; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - tmo = CONFIG_SYS_HZ_CLOCK / 1000; - tmo *= usec; - tmo /= 1000; - - endtime = get_timer_raw () + tmo; - - do { - ulong now = get_timer_raw (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/arm920t/at91rm9200/timer.c b/cpu/arm920t/at91rm9200/timer.c new file mode 100644 index 0000000000..235d107388 --- /dev/null +++ b/cpu/arm920t/at91rm9200/timer.c @@ -0,0 +1,160 @@ +/* + * (C) Copyright 2002 + * Lineo, Inc. + * Bernhard Kuhn + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +/*#include */ +#include +/*#include */ + +/* the number of clocks per CONFIG_SYS_HZ */ +#define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) + +/* macro to read the 16 bit timer */ +#define READ_TIMER (tmr->TC_CV & 0x0000ffff) +AT91PS_TC tmr; + +static ulong timestamp; +static ulong lastinc; + +int timer_init (void) +{ + tmr = AT91C_BASE_TC0; + + /* enables TC1.0 clock */ + *AT91C_PMC_PCER = 1 << AT91C_ID_TC0; /* enable clock */ + + *AT91C_TCB0_BCR = 0; + *AT91C_TCB0_BMR = AT91C_TCB_TC0XC0S_NONE | AT91C_TCB_TC1XC1S_NONE | AT91C_TCB_TC2XC2S_NONE; + tmr->TC_CCR = AT91C_TC_CLKDIS; +#define AT91C_TC_CMR_CPCTRG (1 << 14) + /* set to MCLK/2 and restart the timer when the vlaue in TC_RC is reached */ + tmr->TC_CMR = AT91C_TC_TIMER_DIV1_CLOCK | AT91C_TC_CMR_CPCTRG; + + tmr->TC_IDR = ~0ul; + tmr->TC_RC = TIMER_LOAD_VAL; + lastinc = 0; + tmr->TC_CCR = AT91C_TC_SWTRG | AT91C_TC_CLKEN; + timestamp = 0; + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void udelay (unsigned long usec) +{ + udelay_masked(usec); +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastinc = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_raw (void) +{ + ulong now = READ_TIMER; + + if (now >= lastinc) { + /* normal mode */ + timestamp += now - lastinc; + } else { + /* we have an overflow ... */ + timestamp += now + TIMER_LOAD_VAL - lastinc; + } + lastinc = now; + + return timestamp; +} + +ulong get_timer_masked (void) +{ + return get_timer_raw()/TIMER_LOAD_VAL; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + tmo = CONFIG_SYS_HZ_CLOCK / 1000; + tmo *= usec; + tmo /= 1000; + + endtime = get_timer_raw () + tmo; + + do { + ulong now = get_timer_raw (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/cpu/arm920t/imx/Makefile b/cpu/arm920t/imx/Makefile index d3352deb4b..28945e22cb 100644 --- a/cpu/arm920t/imx/Makefile +++ b/cpu/arm920t/imx/Makefile @@ -25,7 +25,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).a -COBJS = generic.o interrupts.o speed.o +COBJS += generic.o +COBJS += speed.o +COBJS += timer.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/arm920t/imx/interrupts.c b/cpu/arm920t/imx/interrupts.c deleted file mode 100644 index 1beaf9dcf5..0000000000 --- a/cpu/arm920t/imx/interrupts.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#if defined (CONFIG_IMX) - -#include -#include - -int interrupt_init (void) -{ - int i; - /* setup GP Timer 1 */ - TCTL1 = TCTL_SWR; - for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */ - TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */ - TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */ - - reset_timer_masked(); - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer (ulong t) -{ - /* nop */ -} - -void reset_timer_masked (void) -{ - TCTL1 &= ~TCTL_TEN; - TCTL1 |= TCTL_TEN; /* Enable timer */ -} - -ulong get_timer_masked (void) -{ - return TCN1; -} - -void udelay_masked (unsigned long usec) -{ - ulong endtime = get_timer_masked() + usec; - signed long diff; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -void udelay (unsigned long usec) -{ - udelay_masked(usec); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - - return tbclk; -} - -/* - * Reset the cpu by setting up the watchdog timer and let him time out - */ -void reset_cpu (ulong ignored) -{ - /* Disable watchdog and set Time-Out field to 0 */ - WCR = 0x00000000; - - /* Write Service Sequence */ - WSR = 0x00005555; - WSR = 0x0000AAAA; - - /* Enable watchdog */ - WCR = 0x00000001; - - while (1); - /*NOTREACHED*/ -} - -#endif /* defined (CONFIG_IMX) */ diff --git a/cpu/arm920t/imx/timer.c b/cpu/arm920t/imx/timer.c new file mode 100644 index 0000000000..280c682940 --- /dev/null +++ b/cpu/arm920t/imx/timer.c @@ -0,0 +1,139 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#if defined (CONFIG_IMX) + +#include +#include + +int timer_init (void) +{ + int i; + /* setup GP Timer 1 */ + TCTL1 = TCTL_SWR; + for ( i=0; i<100; i++) TCTL1 = 0; /* We have no udelay by now */ + TPRER1 = get_PERCLK1() / 1000000; /* 1 MHz */ + TCTL1 |= TCTL_FRR | (1<<1); /* Freerun Mode, PERCLK1 input */ + + reset_timer_masked(); + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer (ulong t) +{ + /* nop */ +} + +void reset_timer_masked (void) +{ + TCTL1 &= ~TCTL_TEN; + TCTL1 |= TCTL_TEN; /* Enable timer */ +} + +ulong get_timer_masked (void) +{ + return TCN1; +} + +void udelay_masked (unsigned long usec) +{ + ulong endtime = get_timer_masked() + usec; + signed long diff; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +void udelay (unsigned long usec) +{ + udelay_masked(usec); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + + return tbclk; +} + +/* + * Reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu (ulong ignored) +{ + /* Disable watchdog and set Time-Out field to 0 */ + WCR = 0x00000000; + + /* Write Service Sequence */ + WSR = 0x00005555; + WSR = 0x0000AAAA; + + /* Enable watchdog */ + WCR = 0x00000001; + + while (1); + /*NOTREACHED*/ +} + +#endif /* defined (CONFIG_IMX) */ diff --git a/cpu/arm920t/ks8695/Makefile b/cpu/arm920t/ks8695/Makefile index f6b006300b..f53fdc2b25 100644 --- a/cpu/arm920t/ks8695/Makefile +++ b/cpu/arm920t/ks8695/Makefile @@ -25,9 +25,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).a -COBJS = interrupts.o SOBJS = lowlevel_init.o +COBJS = timer.o + SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/arm920t/ks8695/interrupts.c b/cpu/arm920t/ks8695/interrupts.c deleted file mode 100644 index 883d689ed0..0000000000 --- a/cpu/arm920t/ks8695/interrupts.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * (C) Copyright 2004-2005, Greg Ungerer - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -/* - * Handy KS8695 register access functions. - */ -#define ks8695_read(a) *((volatile ulong *) (KS8695_IO_BASE + (a))) -#define ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v) - -int timer_inited; -ulong timer_ticks; - -int interrupt_init (void) -{ - /* nothing happens here - we don't setup any IRQs */ - return (0); -} - -/* - * Initial timer set constants. Nothing complicated, just set for a 1ms - * tick. - */ -#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_1) -#define TIMER_COUNT (TIMER_INTERVAL / 2) -#define TIMER_PULSE TIMER_COUNT - -void reset_timer_masked(void) -{ - /* Set the hadware timer for 1ms */ - ks8695_write(KS8695_TIMER1, TIMER_COUNT); - ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE); - ks8695_write(KS8695_TIMER_CTRL, 0x2); - timer_ticks = 0; - timer_inited++; -} - -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer_masked(void) -{ - /* Check for timer wrap */ - if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) { - /* Clear interrupt condition */ - ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1); - timer_ticks++; - } - return timer_ticks; -} - -ulong get_timer(ulong base) -{ - return (get_timer_masked() - base); -} - -void set_timer(ulong t) -{ - timer_ticks = t; -} - -void udelay(ulong usec) -{ - ulong start = get_timer_masked(); - ulong end; - - if (!timer_inited) - reset_timer(); - - /* Only 1ms resolution :-( */ - end = usec / 1000; - while (get_timer(start) < end) - ; -} - -void reset_cpu (ulong ignored) -{ - ulong tc; - - /* Set timer0 to watchdog, and let it timeout */ - tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2; - ks8695_write(KS8695_TIMER_CTRL, tc); - ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff)); - ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1)); - - /* Should only wait here till watchdog resets */ - for (;;) - ; -} diff --git a/cpu/arm920t/ks8695/timer.c b/cpu/arm920t/ks8695/timer.c new file mode 100644 index 0000000000..22987bc48b --- /dev/null +++ b/cpu/arm920t/ks8695/timer.c @@ -0,0 +1,108 @@ +/* + * (C) Copyright 2004-2005, Greg Ungerer + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* + * Handy KS8695 register access functions. + */ +#define ks8695_read(a) *((volatile ulong *) (KS8695_IO_BASE + (a))) +#define ks8695_write(a,v) *((volatile ulong *) (KS8695_IO_BASE + (a))) = (v) + +ulong timer_ticks; + +int timer_init (void) +{ + reset_timer(); + + return 0; +} + +/* + * Initial timer set constants. Nothing complicated, just set for a 1ms + * tick. + */ +#define TIMER_INTERVAL (TICKS_PER_uSEC * mSEC_1) +#define TIMER_COUNT (TIMER_INTERVAL / 2) +#define TIMER_PULSE TIMER_COUNT + +void reset_timer_masked(void) +{ + /* Set the hadware timer for 1ms */ + ks8695_write(KS8695_TIMER1, TIMER_COUNT); + ks8695_write(KS8695_TIMER1_PCOUNT, TIMER_PULSE); + ks8695_write(KS8695_TIMER_CTRL, 0x2); + timer_ticks = 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer_masked(void) +{ + /* Check for timer wrap */ + if (ks8695_read(KS8695_INT_STATUS) & KS8695_INTMASK_TIMERINT1) { + /* Clear interrupt condition */ + ks8695_write(KS8695_INT_STATUS, KS8695_INTMASK_TIMERINT1); + timer_ticks++; + } + return timer_ticks; +} + +ulong get_timer(ulong base) +{ + return (get_timer_masked() - base); +} + +void set_timer(ulong t) +{ + timer_ticks = t; +} + +void udelay(ulong usec) +{ + ulong start = get_timer_masked(); + ulong end; + + /* Only 1ms resolution :-( */ + end = usec / 1000; + while (get_timer(start) < end) + ; +} + +void reset_cpu (ulong ignored) +{ + ulong tc; + + /* Set timer0 to watchdog, and let it timeout */ + tc = ks8695_read(KS8695_TIMER_CTRL) & 0x2; + ks8695_write(KS8695_TIMER_CTRL, tc); + ks8695_write(KS8695_TIMER0, ((10 << 8) | 0xff)); + ks8695_write(KS8695_TIMER_CTRL, (tc | 0x1)); + + /* Should only wait here till watchdog resets */ + for (;;) + ; +} diff --git a/cpu/arm920t/s3c24x0/Makefile b/cpu/arm920t/s3c24x0/Makefile index 3afe19ce9c..5d2be2c1b2 100644 --- a/cpu/arm920t/s3c24x0/Makefile +++ b/cpu/arm920t/s3c24x0/Makefile @@ -25,7 +25,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).a -COBJS = interrupts.o speed.o usb.o usb_ohci.o +COBJS += speed.o +COBJS += timer.o +COBJS += usb.o +COBJS += usb_ohci.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/arm920t/s3c24x0/interrupts.c b/cpu/arm920t/s3c24x0/interrupts.c deleted file mode 100644 index b8ce6ae94a..0000000000 --- a/cpu/arm920t/s3c24x0/interrupts.c +++ /dev/null @@ -1,228 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) - -#include -#if defined(CONFIG_S3C2400) -#include -#elif defined(CONFIG_S3C2410) -#include -#endif - -int timer_load_val = 0; - -/* macro to read the 16 bit timer */ -static inline ulong READ_TIMER(void) -{ - S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS(); - - return (timers->TCNTO4 & 0xffff); -} - -static ulong timestamp; -static ulong lastdec; - -int interrupt_init (void) -{ - S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS(); - - /* use PWM Timer 4 because it has no output */ - /* prescaler for Timer 4 is 16 */ - timers->TCFG0 = 0x0f00; - if (timer_load_val == 0) - { - /* - * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 - * (default) and prescaler = 16. Should be 10390 - * @33.25MHz and 15625 @ 50 MHz - */ - timer_load_val = get_PCLK()/(2 * 16 * 100); - } - /* load value for 10 ms timeout */ - lastdec = timers->TCNTB4 = timer_load_val; - /* auto load, manual update of Timer 4 */ - timers->TCON = (timers->TCON & ~0x0700000) | 0x600000; - /* auto load, start Timer 4 */ - timers->TCON = (timers->TCON & ~0x0700000) | 0x500000; - timestamp = 0; - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -void udelay (unsigned long usec) -{ - ulong tmo; - ulong start = get_timer(0); - - tmo = usec / 1000; - tmo *= (timer_load_val * 100); - tmo /= 1000; - - while ((ulong)(get_timer_masked () - start) < tmo) - /*NOP*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER(); - timestamp = 0; -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + timer_load_val - now; - } - lastdec = now; - - return timestamp; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= (timer_load_val * 100); - tmo /= 1000; - } else { - tmo = usec * (timer_load_val * 100); - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - -#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB) - tbclk = timer_load_val * 100; -#elif defined(CONFIG_SBC2410X) || \ - defined(CONFIG_SMDK2410) || \ - defined(CONFIG_VCMA9) - tbclk = CONFIG_SYS_HZ; -#else -# error "tbclk not configured" -#endif - - return tbclk; -} - -/* - * reset the cpu by setting up the watchdog timer and let him time out - */ -void reset_cpu (ulong ignored) -{ - volatile S3C24X0_WATCHDOG * watchdog; - -#ifdef CONFIG_TRAB - extern void disable_vfd (void); - - disable_vfd(); -#endif - - watchdog = S3C24X0_GetBase_WATCHDOG(); - - /* Disable watchdog */ - watchdog->WTCON = 0x0000; - - /* Initialize watchdog timer count register */ - watchdog->WTCNT = 0x0001; - - /* Enable watchdog timer; assert reset at timer timeout */ - watchdog->WTCON = 0x0021; - - while(1); /* loop forever and wait for reset to happen */ - - /*NOTREACHED*/ -} - -#ifdef CONFIG_USE_IRQ -void s3c2410_irq(void) -{ - S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT(); - u_int32_t intpnd = irq->INTPND; - -} -#endif /* USE_IRQ */ - -#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */ diff --git a/cpu/arm920t/s3c24x0/timer.c b/cpu/arm920t/s3c24x0/timer.c new file mode 100644 index 0000000000..f3c0ed62cc --- /dev/null +++ b/cpu/arm920t/s3c24x0/timer.c @@ -0,0 +1,228 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#if defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) + +#include +#if defined(CONFIG_S3C2400) +#include +#elif defined(CONFIG_S3C2410) +#include +#endif + +int timer_load_val = 0; + +/* macro to read the 16 bit timer */ +static inline ulong READ_TIMER(void) +{ + S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS(); + + return (timers->TCNTO4 & 0xffff); +} + +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + S3C24X0_TIMERS * const timers = S3C24X0_GetBase_TIMERS(); + + /* use PWM Timer 4 because it has no output */ + /* prescaler for Timer 4 is 16 */ + timers->TCFG0 = 0x0f00; + if (timer_load_val == 0) + { + /* + * for 10 ms clock period @ PCLK with 4 bit divider = 1/2 + * (default) and prescaler = 16. Should be 10390 + * @33.25MHz and 15625 @ 50 MHz + */ + timer_load_val = get_PCLK()/(2 * 16 * 100); + } + /* load value for 10 ms timeout */ + lastdec = timers->TCNTB4 = timer_load_val; + /* auto load, manual update of Timer 4 */ + timers->TCON = (timers->TCON & ~0x0700000) | 0x600000; + /* auto load, start Timer 4 */ + timers->TCON = (timers->TCON & ~0x0700000) | 0x500000; + timestamp = 0; + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void udelay (unsigned long usec) +{ + ulong tmo; + ulong start = get_timer(0); + + tmo = usec / 1000; + tmo *= (timer_load_val * 100); + tmo /= 1000; + + while ((ulong)(get_timer_masked () - start) < tmo) + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + timer_load_val - now; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= (timer_load_val * 100); + tmo /= 1000; + } else { + tmo = usec * (timer_load_val * 100); + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + +#if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB) + tbclk = timer_load_val * 100; +#elif defined(CONFIG_SBC2410X) || \ + defined(CONFIG_SMDK2410) || \ + defined(CONFIG_VCMA9) + tbclk = CONFIG_SYS_HZ; +#else +# error "tbclk not configured" +#endif + + return tbclk; +} + +/* + * reset the cpu by setting up the watchdog timer and let him time out + */ +void reset_cpu (ulong ignored) +{ + volatile S3C24X0_WATCHDOG * watchdog; + +#ifdef CONFIG_TRAB + extern void disable_vfd (void); + + disable_vfd(); +#endif + + watchdog = S3C24X0_GetBase_WATCHDOG(); + + /* Disable watchdog */ + watchdog->WTCON = 0x0000; + + /* Initialize watchdog timer count register */ + watchdog->WTCNT = 0x0001; + + /* Enable watchdog timer; assert reset at timer timeout */ + watchdog->WTCON = 0x0021; + + while(1); /* loop forever and wait for reset to happen */ + + /*NOTREACHED*/ +} + +#ifdef CONFIG_USE_IRQ +void s3c2410_irq(void) +{ + S3C24X0_INTERRUPT * irq = S3C24X0_GetBase_INTERRUPT(); + u_int32_t intpnd = irq->INTPND; + +} +#endif /* USE_IRQ */ + +#endif /* defined(CONFIG_S3C2400) || defined (CONFIG_S3C2410) || defined (CONFIG_TRAB) */ diff --git a/cpu/arm925t/Makefile b/cpu/arm925t/Makefile index 0d4912cd72..8d0e88f902 100644 --- a/cpu/arm925t/Makefile +++ b/cpu/arm925t/Makefile @@ -26,7 +26,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = interrupts.o cpu.o omap925.o + +COBJS += cpu.o +COBJS += omap925.o +COBJS += timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/arm925t/interrupts.c b/cpu/arm925t/interrupts.c deleted file mode 100644 index 179992debe..0000000000 --- a/cpu/arm925t/interrupts.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * (C) Copyright 2009 - * 2N Telekomunikace, - * - * (C) Copyright 2003 - * Texas Instruments, - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include -#include - -#define TIMER_LOAD_VAL 0xffffffff -#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV)) - -static uint32_t timestamp; -static uint32_t lastdec; - -/* nothing really to do with interrupts, just starts up a counter. */ -int interrupt_init (void) -{ - /* Start the decrementer ticking down from 0xffffffff */ - __raw_writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + LOAD_TIM); - __raw_writel(MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | - (CONFIG_SYS_PTV << MPUTIM_PTV_BIT), - CONFIG_SYS_TIMERBASE + CNTL_TIMER); - - /* init the timestamp and lastdec value */ - reset_timer_masked(); - - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -/* delay x useconds AND preserve advance timestamp value */ -void udelay (unsigned long usec) -{ - int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000; - uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); - - while (tmo > 0) { - now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); - if (last < now) /* count down timer underflow */ - tmo -= TIMER_LOAD_VAL - now + last; - else - tmo -= last - now; - last = now; - } -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / - (TIMER_CLOCK / CONFIG_SYS_HZ); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked (void) -{ - uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / - (TIMER_CLOCK / CONFIG_SYS_HZ); - if (lastdec < now) /* count down timer underflow */ - timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) - - now + lastdec; - else - timestamp += lastdec - now; - lastdec = now; - - return timestamp; -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm925t/timer.c b/cpu/arm925t/timer.c new file mode 100644 index 0000000000..c16ef2577f --- /dev/null +++ b/cpu/arm925t/timer.c @@ -0,0 +1,137 @@ +/* + * (C) Copyright 2009 + * 2N Telekomunikace, + * + * (C) Copyright 2003 + * Texas Instruments, + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include + +#define TIMER_LOAD_VAL 0xffffffff +#define TIMER_CLOCK (CONFIG_SYS_CLK_FREQ / (2 << CONFIG_SYS_PTV)) + +static uint32_t timestamp; +static uint32_t lastdec; + +/* nothing really to do with interrupts, just starts up a counter. */ +int timer_init (void) +{ + /* Start the decrementer ticking down from 0xffffffff */ + __raw_writel(TIMER_LOAD_VAL, CONFIG_SYS_TIMERBASE + LOAD_TIM); + __raw_writel(MPUTIM_ST | MPUTIM_AR | MPUTIM_CLOCK_ENABLE | + (CONFIG_SYS_PTV << MPUTIM_PTV_BIT), + CONFIG_SYS_TIMERBASE + CNTL_TIMER); + + /* init the timestamp and lastdec value */ + reset_timer_masked(); + + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +/* delay x useconds AND preserve advance timestamp value */ +void udelay (unsigned long usec) +{ + int32_t tmo = usec * (TIMER_CLOCK / 1000) / 1000; + uint32_t now, last = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); + + while (tmo > 0) { + now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM); + if (last < now) /* count down timer underflow */ + tmo -= TIMER_LOAD_VAL - now + last; + else + tmo -= last - now; + last = now; + } +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / + (TIMER_CLOCK / CONFIG_SYS_HZ); + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked (void) +{ + uint32_t now = __raw_readl(CONFIG_SYS_TIMERBASE + READ_TIM) / + (TIMER_CLOCK / CONFIG_SYS_HZ); + if (lastdec < now) /* count down timer underflow */ + timestamp += TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ) - + now + lastdec; + else + timestamp += lastdec - now; + lastdec = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + return CONFIG_SYS_HZ; +} diff --git a/cpu/arm926ejs/Makefile b/cpu/arm926ejs/Makefile index d5ac7d3fd9..7701b03bbe 100644 --- a/cpu/arm926ejs/Makefile +++ b/cpu/arm926ejs/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = interrupts.o cpu.o +COBJS = cpu.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/cpu/arm926ejs/interrupts.c b/cpu/arm926ejs/interrupts.c deleted file mode 100644 index ce979f3d87..0000000000 --- a/cpu/arm926ejs/interrupts.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * (C) Copyright 2003 - * Texas Instruments - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002-2004 - * Gary Jennejohn, DENX Software Engineering, - * - * (C) Copyright 2004 - * Philippe Robin, ARM Ltd. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#ifdef CONFIG_INTEGRATOR - - /* Timer functionality supplied by Integrator board (AP or CP) */ - -#else - -/* nothing really to do with interrupts, just starts up a counter. */ -int interrupt_init (void) -{ - extern void timer_init(void); - - timer_init(); - - return 0; -} - -#endif /* CONFIG_INTEGRATOR */ diff --git a/cpu/arm_cortexa8/omap3/Makefile b/cpu/arm_cortexa8/omap3/Makefile index d1e658d57c..edf5cb29a7 100644 --- a/cpu/arm_cortexa8/omap3/Makefile +++ b/cpu/arm_cortexa8/omap3/Makefile @@ -32,7 +32,7 @@ COBJS += clock.o COBJS += mem.o COBJS += syslib.o COBJS += sys_info.o -COBJS += interrupts.o +COBJS += timer.o SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS) $(SOBJS)) diff --git a/cpu/arm_cortexa8/omap3/interrupts.c b/cpu/arm_cortexa8/omap3/interrupts.c deleted file mode 100644 index 3fe13fbaaf..0000000000 --- a/cpu/arm_cortexa8/omap3/interrupts.c +++ /dev/null @@ -1,138 +0,0 @@ -/* - * (C) Copyright 2008 - * Texas Instruments - * - * Richard Woodruff - * Syed Moahmmed Khasim - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -static ulong timestamp; -static ulong lastinc; -static gptimer_t *timer_base = (gptimer_t *)CONFIG_SYS_TIMERBASE; - -/* - * Nothing really to do with interrupts, just starts up a counter. - * We run the counter with 13MHz, divided by 8, resulting in timer - * frequency of 1.625MHz. With 32bit counter register, counter - * overflows in ~44min - */ - -/* 13MHz / 8 = 1.625MHz */ -#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV)) -#define TIMER_LOAD_VAL 0xffffffff - -int interrupt_init(void) -{ - /* start the counter ticking up, reload value on overflow */ - writel(TIMER_LOAD_VAL, &timer_base->tldr); - /* enable timer */ - writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST, - &timer_base->tclr); - - reset_timer_masked(); /* init the timestamp and lastinc value */ - - return 0; -} - -/* - * timer without interrupts - */ -void reset_timer(void) -{ - reset_timer_masked(); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -void set_timer(ulong t) -{ - timestamp = t; -} - -/* delay x useconds */ -void udelay(unsigned long usec) -{ - long tmo = usec * (TIMER_CLOCK / 1000) / 1000; - unsigned long now, last = readl(&timer_base->tcrr); - - while (tmo > 0) { - now = readl(&timer_base->tcrr); - if (last > now) /* count up timer overflow */ - tmo -= TIMER_LOAD_VAL - last + now; - else - tmo -= now - last; - last = now; - } -} - -void reset_timer_masked(void) -{ - /* reset time, capture current incrementer value time */ - lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); - timestamp = 0; /* start "advancing" time stamp from 0 */ -} - -ulong get_timer_masked(void) -{ - /* current tick value */ - ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); - - if (now >= lastinc) /* normal mode (non roll) */ - /* move stamp fordward with absoulte diff ticks */ - timestamp += (now - lastinc); - else /* we have rollover of incrementer */ - timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ)) - - lastinc) + now; - lastinc = now; - return timestamp; -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return CONFIG_SYS_HZ; -} diff --git a/cpu/arm_cortexa8/omap3/timer.c b/cpu/arm_cortexa8/omap3/timer.c new file mode 100644 index 0000000000..05cfe763aa --- /dev/null +++ b/cpu/arm_cortexa8/omap3/timer.c @@ -0,0 +1,138 @@ +/* + * (C) Copyright 2008 + * Texas Instruments + * + * Richard Woodruff + * Syed Moahmmed Khasim + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +static ulong timestamp; +static ulong lastinc; +static gptimer_t *timer_base = (gptimer_t *)CONFIG_SYS_TIMERBASE; + +/* + * Nothing really to do with interrupts, just starts up a counter. + * We run the counter with 13MHz, divided by 8, resulting in timer + * frequency of 1.625MHz. With 32bit counter register, counter + * overflows in ~44min + */ + +/* 13MHz / 8 = 1.625MHz */ +#define TIMER_CLOCK (V_SCLK / (2 << CONFIG_SYS_PTV)) +#define TIMER_LOAD_VAL 0xffffffff + +int timer_init(void) +{ + /* start the counter ticking up, reload value on overflow */ + writel(TIMER_LOAD_VAL, &timer_base->tldr); + /* enable timer */ + writel((CONFIG_SYS_PTV << 2) | TCLR_PRE | TCLR_AR | TCLR_ST, + &timer_base->tclr); + + reset_timer_masked(); /* init the timestamp and lastinc value */ + + return 0; +} + +/* + * timer without interrupts + */ +void reset_timer(void) +{ + reset_timer_masked(); +} + +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +void set_timer(ulong t) +{ + timestamp = t; +} + +/* delay x useconds */ +void udelay(unsigned long usec) +{ + long tmo = usec * (TIMER_CLOCK / 1000) / 1000; + unsigned long now, last = readl(&timer_base->tcrr); + + while (tmo > 0) { + now = readl(&timer_base->tcrr); + if (last > now) /* count up timer overflow */ + tmo -= TIMER_LOAD_VAL - last + now; + else + tmo -= now - last; + last = now; + } +} + +void reset_timer_masked(void) +{ + /* reset time, capture current incrementer value time */ + lastinc = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); + timestamp = 0; /* start "advancing" time stamp from 0 */ +} + +ulong get_timer_masked(void) +{ + /* current tick value */ + ulong now = readl(&timer_base->tcrr) / (TIMER_CLOCK / CONFIG_SYS_HZ); + + if (now >= lastinc) /* normal mode (non roll) */ + /* move stamp fordward with absoulte diff ticks */ + timestamp += (now - lastinc); + else /* we have rollover of incrementer */ + timestamp += ((TIMER_LOAD_VAL / (TIMER_CLOCK / CONFIG_SYS_HZ)) + - lastinc) + now; + lastinc = now; + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/cpu/ixp/Makefile b/cpu/ixp/Makefile index a673cb1b9f..1403c4f390 100644 --- a/cpu/ixp/Makefile +++ b/cpu/ixp/Makefile @@ -26,12 +26,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o + COBJS-y += cpu.o -ifndef CONFIG_USE_IRQ +COBJS-$(CONFIG_USE_IRQ) += interrupts.o COBJS-y += timer.o -else -COBJS-y += interrupts.o -endif SRCS := $(START:.o=.S) $(SOBJS-y:.o=.S) $(COBJS-y:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) diff --git a/cpu/ixp/interrupts.c b/cpu/ixp/interrupts.c index ee0129ead3..a05e439fdb 100644 --- a/cpu/ixp/interrupts.c +++ b/cpu/ixp/interrupts.c @@ -33,14 +33,6 @@ #include #include -/* - * When interrupts are enabled, use timer 2 for time/delay generation... - */ - -#define FREQ 66666666 -#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ) -#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */ - struct _irq_handler { void *m_data; void (*m_func)( void *data); @@ -48,8 +40,6 @@ struct _irq_handler { static struct _irq_handler IRQ_HANDLER[N_IRQS]; -static volatile ulong timestamp; - static void default_isr(void *data) { printf("default_isr(): called for IRQ %d, Interrupt Status=%x PR=%x\n", @@ -61,33 +51,20 @@ static int next_irq(void) return (((*IXP425_ICIH & 0x000000fc) >> 2) - 1); } -static void timer_isr(void *data) -{ - unsigned int *pTime = (unsigned int *)data; - - (*pTime)++; - - /* - * Reset IRQ source - */ - *IXP425_OSST = IXP425_OSST_TIMER_2_PEND; -} - -ulong get_timer (ulong base) +void do_irq (struct pt_regs *pt_regs) { - return timestamp - base; -} + int irq = next_irq(); -void reset_timer (void) -{ - timestamp = 0; + IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data); } -void do_irq (struct pt_regs *pt_regs) +void irq_install_handler (int irq, interrupt_handler_t handle_irq, void *data) { - int irq = next_irq(); + if (irq >= N_IRQS || !handle_irq) + return; - IRQ_HANDLER[irq].m_func(IRQ_HANDLER[irq].m_data); + IRQ_HANDLER[irq].m_data = data; + IRQ_HANDLER[irq].m_func = handle_irq; } int interrupt_init (void) @@ -95,23 +72,11 @@ int interrupt_init (void) int i; /* install default interrupt handlers */ - for (i = 0; i < N_IRQS; i++) { - IRQ_HANDLER[i].m_data = (void *)i; - IRQ_HANDLER[i].m_func = default_isr; - } - - /* install interrupt handler for timer */ - IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_data = (void *)×tamp; - IRQ_HANDLER[IXP425_TIMER_2_IRQ].m_func = timer_isr; - - /* setup the Timer counter value */ - *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE; + for (i = 0; i < N_IRQS; i++) + irq_install_handler(i, default_isr, (void *)i); /* configure interrupts for IRQ mode */ *IXP425_ICLR = 0x00000000; - /* enable timer irq */ - *IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ); - return (0); } diff --git a/cpu/ixp/timer.c b/cpu/ixp/timer.c index deb227a1a6..685614966b 100644 --- a/cpu/ixp/timer.c +++ b/cpu/ixp/timer.c @@ -32,6 +32,54 @@ #include #include +#ifdef CONFIG_TIMER_IRQ + +#define FREQ 66666666 +#define CLOCK_TICK_RATE (((FREQ / CONFIG_SYS_HZ & ~IXP425_OST_RELOAD_MASK) + 1) * CONFIG_SYS_HZ) +#define LATCH ((CLOCK_TICK_RATE + CONFIG_SYS_HZ/2) / CONFIG_SYS_HZ) /* For divider */ + +/* + * When interrupts are enabled, use timer 2 for time/delay generation... + */ + +static volatile ulong timestamp; + +static void timer_isr(void *data) +{ + unsigned int *pTime = (unsigned int *)data; + + (*pTime)++; + + /* + * Reset IRQ source + */ + *IXP425_OSST = IXP425_OSST_TIMER_2_PEND; +} + +ulong get_timer (ulong base) +{ + return timestamp - base; +} + +void reset_timer (void) +{ + timestamp = 0; +} + +int timer_init (void) +{ + /* install interrupt handler for timer */ + irq_install_handler(IXP425_TIMER_2_IRQ, timer_isr, (void *)×tamp); + + /* setup the Timer counter value */ + *IXP425_OSRT2 = (LATCH & ~IXP425_OST_RELOAD_MASK) | IXP425_OST_ENABLE; + + /* enable timer irq */ + *IXP425_ICMR = (1 << IXP425_TIMER_2_IRQ); + + return 0; +} +#else ulong get_timer (ulong base) { return get_timer_masked () - base; @@ -79,3 +127,9 @@ ulong get_timer_masked (void) } return (reload_constant - current); } + +int timer_init(void) +{ + return 0; +} +#endif diff --git a/cpu/lh7a40x/Makefile b/cpu/lh7a40x/Makefile index bac2a640cb..b9ae76effa 100644 --- a/cpu/lh7a40x/Makefile +++ b/cpu/lh7a40x/Makefile @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = cpu.o speed.o interrupts.o serial.o +COBJS = cpu.o speed.o serial.o timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/lh7a40x/interrupts.c b/cpu/lh7a40x/interrupts.c deleted file mode 100644 index d39e707775..0000000000 --- a/cpu/lh7a40x/interrupts.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * (C) Copyright 2002 - * Gary Jennejohn, DENX Software Engineering, - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -static ulong timer_load_val = 0; - -/* macro to read the 16 bit timer */ -static inline ulong READ_TIMER(void) -{ - lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; - lh7a40x_timer_t* timer = &timers->timer1; - - return (timer->value & 0x0000ffff); -} - -static ulong timestamp; -static ulong lastdec; - -int interrupt_init (void) -{ - lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; - lh7a40x_timer_t* timer = &timers->timer1; - - /* a periodic timer using the 508kHz source */ - timer->control = (TIMER_PER | TIMER_CLK508K); - - if (timer_load_val == 0) { - /* - * 10ms period with 508.469kHz clock = 5084 - */ - timer_load_val = CONFIG_SYS_HZ/100; - } - - /* load value for 10 ms timeout */ - lastdec = timer->load = timer_load_val; - - /* auto load, start timer */ - timer->control = timer->control | TIMER_EN; - timestamp = 0; - - return (0); -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return (get_timer_masked() - base); -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -void udelay (unsigned long usec) -{ - ulong tmo,tmp; - - /* normalize */ - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 1000; - } - else { - if (usec > 1) { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - else - tmo = 1; - } - - /* check for rollover during this delay */ - tmp = get_timer (0); - if ((tmp + tmo) < tmp ) - reset_timer_masked(); /* timer would roll over */ - else - tmo += tmp; - - while (get_timer_masked () < tmo); -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER(); - timestamp = 0; -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER(); - - if (lastdec >= now) { - /* normal mode */ - timestamp += (lastdec - now); - } else { - /* we have an overflow ... */ - timestamp += ((lastdec + timer_load_val) - now); - } - lastdec = now; - - return timestamp; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - /* normalize */ - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 1000; - } else { - if (usec > 1) { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } else { - tmo = 1; - } - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = timer_load_val * 100; - - return tbclk; -} diff --git a/cpu/lh7a40x/timer.c b/cpu/lh7a40x/timer.c new file mode 100644 index 0000000000..f0baf14737 --- /dev/null +++ b/cpu/lh7a40x/timer.c @@ -0,0 +1,194 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +static ulong timer_load_val = 0; + +/* macro to read the 16 bit timer */ +static inline ulong READ_TIMER(void) +{ + lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; + lh7a40x_timer_t* timer = &timers->timer1; + + return (timer->value & 0x0000ffff); +} + +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + lh7a40x_timers_t* timers = LH7A40X_TIMERS_PTR; + lh7a40x_timer_t* timer = &timers->timer1; + + /* a periodic timer using the 508kHz source */ + timer->control = (TIMER_PER | TIMER_CLK508K); + + if (timer_load_val == 0) { + /* + * 10ms period with 508.469kHz clock = 5084 + */ + timer_load_val = CONFIG_SYS_HZ/100; + } + + /* load value for 10 ms timeout */ + lastdec = timer->load = timer_load_val; + + /* auto load, start timer */ + timer->control = timer->control | TIMER_EN; + timestamp = 0; + + return (0); +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return (get_timer_masked() - base); +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void udelay (unsigned long usec) +{ + ulong tmo,tmp; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + } + else { + if (usec > 1) { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + else + tmo = 1; + } + + /* check for rollover during this delay */ + tmp = get_timer (0); + if ((tmp + tmo) < tmp ) + reset_timer_masked(); /* timer would roll over */ + else + tmo += tmp; + + while (get_timer_masked () < tmo); +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER(); + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER(); + + if (lastdec >= now) { + /* normal mode */ + timestamp += (lastdec - now); + } else { + /* we have an overflow ... */ + timestamp += ((lastdec + timer_load_val) - now); + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + /* normalize */ + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + } else { + if (usec > 1) { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } else { + tmo = 1; + } + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = timer_load_val * 100; + + return tbclk; +} diff --git a/cpu/pxa/Makefile b/cpu/pxa/Makefile index 42903b2ea4..5dc3a52c8d 100644 --- a/cpu/pxa/Makefile +++ b/cpu/pxa/Makefile @@ -26,7 +26,13 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = serial.o interrupts.o cpu.o i2c.o pxafb.o usb.o + +COBJS += cpu.o +COBJS += i2c.o +COBJS += pxafb.o +COBJS += serial.o +COBJS += timer.o +COBJS += usb.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/pxa/interrupts.c b/cpu/pxa/interrupts.c deleted file mode 100644 index 2bc5c50a91..0000000000 --- a/cpu/pxa/interrupts.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include -#include - -#ifdef CONFIG_USE_IRQ -#error: interrupts not implemented yet -#endif - -#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) -#define TIMER_FREQ_HZ 3250000 -#elif defined(CONFIG_PXA250) -#define TIMER_FREQ_HZ 3686400 -#else -#error "Timer frequency unknown - please config PXA CPU type" -#endif - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, TIMER_FREQ_HZ); - return tick; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * TIMER_FREQ_HZ + 999999; - do_div(us, 1000000); - return us; -} - -int interrupt_init (void) -{ - /* nothing happens here - we don't setup any IRQs */ - return (0); -} - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - /* nop */ -} - -void udelay (unsigned long usec) -{ - udelay_masked (usec); -} - - -void reset_timer_masked (void) -{ - OSCR = 0; -} - -ulong get_timer_masked (void) -{ - return tick_to_time(get_ticks()); -} - -void udelay_masked (unsigned long usec) -{ - 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*/; - -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return OSCR; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - tbclk = TIMER_FREQ_HZ; - return tbclk; -} diff --git a/cpu/pxa/timer.c b/cpu/pxa/timer.c new file mode 100644 index 0000000000..e2df3a57fc --- /dev/null +++ b/cpu/pxa/timer.c @@ -0,0 +1,128 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#ifdef CONFIG_USE_IRQ +#error: interrupts not implemented yet +#endif + +#if defined(CONFIG_PXA27X) || defined(CONFIG_CPU_MONAHANS) +#define TIMER_FREQ_HZ 3250000 +#elif defined(CONFIG_PXA250) +#define TIMER_FREQ_HZ 3686400 +#else +#error "Timer frequency unknown - please config PXA CPU type" +#endif + +static inline unsigned long long tick_to_time(unsigned long long tick) +{ + tick *= CONFIG_SYS_HZ; + do_div(tick, TIMER_FREQ_HZ); + return tick; +} + +static inline unsigned long long us_to_tick(unsigned long long us) +{ + us = us * TIMER_FREQ_HZ + 999999; + do_div(us, 1000000); + return us; +} + +int timer_init (void) +{ + reset_timer(); + + return 0; +} + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + /* nop */ +} + +void udelay (unsigned long usec) +{ + udelay_masked (usec); +} + + +void reset_timer_masked (void) +{ + OSCR = 0; +} + +ulong get_timer_masked (void) +{ + return tick_to_time(get_ticks()); +} + +void udelay_masked (unsigned long usec) +{ + 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*/; + +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return OSCR; +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + tbclk = TIMER_FREQ_HZ; + return tbclk; +} diff --git a/cpu/s3c44b0/Makefile b/cpu/s3c44b0/Makefile index ae909a699f..6da2016f66 100644 --- a/cpu/s3c44b0/Makefile +++ b/cpu/s3c44b0/Makefile @@ -26,7 +26,10 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = cache.o cpu.o interrupts.o + +COBJS += cache.o +COBJS += cpu.o +COBJS += timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/s3c44b0/interrupts.c b/cpu/s3c44b0/interrupts.c deleted file mode 100644 index eb23e6ab11..0000000000 --- a/cpu/s3c44b0/interrupts.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * (C) Copyright 2004 - * DAVE Srl - * http://www.dave-tech.it - * http://www.wawnet.biz - * mailto:info@wawnet.biz - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -/* we always count down the max. */ -#define TIMER_LOAD_VAL 0xffff - -/* macro to read the 16 bit timer */ -#define READ_TIMER (TCNTO1 & 0xffff) - -#ifdef CONFIG_USE_IRQ -#error CONFIG_USE_IRQ NOT supported -#endif - -static ulong timestamp; -static ulong lastdec; - -int interrupt_init (void) -{ - TCFG0 = 0x000000E9; - TCFG1 = 0x00000004; - TCON = 0x00000900; - TCNTB1 = TIMER_LOAD_VAL; - TCMPB1 = 0; - TCON = 0x00000B00; - TCON = 0x00000900; - - - lastdec = TCNTB1 = TIMER_LOAD_VAL; - timestamp = 0; - return 0; -} - -/* - * timer without interrupts - */ - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked () - base; -} - -void set_timer (ulong t) -{ - timestamp = t; -} - -void udelay (unsigned long usec) -{ - ulong tmo; - - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 8; - - tmo += get_timer (0); - - while (get_timer_masked () < tmo) - /*NOP*/; -} - -void reset_timer_masked (void) -{ - /* reset time */ - lastdec = READ_TIMER; - timestamp = 0; -} - -ulong get_timer_masked (void) -{ - ulong now = READ_TIMER; - - if (lastdec >= now) { - /* normal mode */ - timestamp += lastdec - now; - } else { - /* we have an overflow ... */ - timestamp += lastdec + TIMER_LOAD_VAL - now; - } - lastdec = now; - - return timestamp; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 8; - } else { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*8); - } - - endtime = get_timer(0) + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} diff --git a/cpu/s3c44b0/timer.c b/cpu/s3c44b0/timer.c new file mode 100644 index 0000000000..34184abb73 --- /dev/null +++ b/cpu/s3c44b0/timer.c @@ -0,0 +1,136 @@ +/* + * (C) Copyright 2004 + * DAVE Srl + * http://www.dave-tech.it + * http://www.wawnet.biz + * mailto:info@wawnet.biz + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +/* we always count down the max. */ +#define TIMER_LOAD_VAL 0xffff + +/* macro to read the 16 bit timer */ +#define READ_TIMER (TCNTO1 & 0xffff) + +#ifdef CONFIG_USE_IRQ +#error CONFIG_USE_IRQ NOT supported +#endif + +static ulong timestamp; +static ulong lastdec; + +int timer_init (void) +{ + TCFG0 = 0x000000E9; + TCFG1 = 0x00000004; + TCON = 0x00000900; + TCNTB1 = TIMER_LOAD_VAL; + TCMPB1 = 0; + TCON = 0x00000B00; + TCON = 0x00000900; + + + lastdec = TCNTB1 = TIMER_LOAD_VAL; + timestamp = 0; + return 0; +} + +/* + * timer without interrupts + */ + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked () - base; +} + +void set_timer (ulong t) +{ + timestamp = t; +} + +void udelay (unsigned long usec) +{ + ulong tmo; + + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 8; + + tmo += get_timer (0); + + while (get_timer_masked () < tmo) + /*NOP*/; +} + +void reset_timer_masked (void) +{ + /* reset time */ + lastdec = READ_TIMER; + timestamp = 0; +} + +ulong get_timer_masked (void) +{ + ulong now = READ_TIMER; + + if (lastdec >= now) { + /* normal mode */ + timestamp += lastdec - now; + } else { + /* we have an overflow ... */ + timestamp += lastdec + TIMER_LOAD_VAL - now; + } + lastdec = now; + + return timestamp; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 8; + } else { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*8); + } + + endtime = get_timer(0) + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} diff --git a/cpu/sa1100/Makefile b/cpu/sa1100/Makefile index fd696f7efb..28b668267c 100644 --- a/cpu/sa1100/Makefile +++ b/cpu/sa1100/Makefile @@ -26,7 +26,9 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(CPU).a START = start.o -COBJS = interrupts.o cpu.o + +COBJS += cpu.o +COBJS += timer.o SRCS := $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS)) diff --git a/cpu/sa1100/interrupts.c b/cpu/sa1100/interrupts.c deleted file mode 100644 index 2eff045709..0000000000 --- a/cpu/sa1100/interrupts.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Marius Groeger - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH - * Alex Zuepke - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -int interrupt_init (void) -{ - /* nothing happens here - we don't setup any IRQs */ - return (0); -} - -void reset_timer (void) -{ - reset_timer_masked (); -} - -ulong get_timer (ulong base) -{ - return get_timer_masked (); -} - -void set_timer (ulong t) -{ - /* nop */ -} - -void udelay (unsigned long usec) -{ - udelay_masked (usec); -} - - -void reset_timer_masked (void) -{ - OSCR = 0; -} - -ulong get_timer_masked (void) -{ - return OSCR; -} - -void udelay_masked (unsigned long usec) -{ - ulong tmo; - ulong endtime; - signed long diff; - - if (usec >= 1000) { - tmo = usec / 1000; - tmo *= CONFIG_SYS_HZ; - tmo /= 1000; - } else { - tmo = usec * CONFIG_SYS_HZ; - tmo /= (1000*1000); - } - - endtime = get_timer_masked () + tmo; - - do { - ulong now = get_timer_masked (); - diff = endtime - now; - } while (diff >= 0); -} - -/* - * This function is derived from PowerPC code (read timebase as long long). - * On ARM it just returns the timer value. - */ -unsigned long long get_ticks(void) -{ - return get_timer(0); -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk (void) -{ - ulong tbclk; - - tbclk = CONFIG_SYS_HZ; - return tbclk; -} diff --git a/cpu/sa1100/timer.c b/cpu/sa1100/timer.c new file mode 100644 index 0000000000..3f77e815cb --- /dev/null +++ b/cpu/sa1100/timer.c @@ -0,0 +1,110 @@ +/* + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Marius Groeger + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH + * Alex Zuepke + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +int timer_init (void) +{ + return 0; +} + +void reset_timer (void) +{ + reset_timer_masked (); +} + +ulong get_timer (ulong base) +{ + return get_timer_masked (); +} + +void set_timer (ulong t) +{ + /* nop */ +} + +void udelay (unsigned long usec) +{ + udelay_masked (usec); +} + + +void reset_timer_masked (void) +{ + OSCR = 0; +} + +ulong get_timer_masked (void) +{ + return OSCR; +} + +void udelay_masked (unsigned long usec) +{ + ulong tmo; + ulong endtime; + signed long diff; + + if (usec >= 1000) { + tmo = usec / 1000; + tmo *= CONFIG_SYS_HZ; + tmo /= 1000; + } else { + tmo = usec * CONFIG_SYS_HZ; + tmo /= (1000*1000); + } + + endtime = get_timer_masked () + tmo; + + do { + ulong now = get_timer_masked (); + diff = endtime - now; + } while (diff >= 0); +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk (void) +{ + ulong tbclk; + + tbclk = CONFIG_SYS_HZ; + return tbclk; +} diff --git a/include/asm-arm/u-boot-arm.h b/include/asm-arm/u-boot-arm.h index e7d58fe8cd..238d408541 100644 --- a/include/asm-arm/u-boot-arm.h +++ b/include/asm-arm/u-boot-arm.h @@ -62,4 +62,7 @@ void reset_timer_masked (void); ulong get_timer_masked (void); void udelay_masked (unsigned long usec); +/* cpu/.../timer.c */ +int timer_init (void); + #endif /* _U_BOOT_ARM_H_ */ diff --git a/include/configs/ixdpg425.h b/include/configs/ixdpg425.h index 75707e597d..0c092347ca 100644 --- a/include/configs/ixdpg425.h +++ b/include/configs/ixdpg425.h @@ -55,6 +55,7 @@ */ #undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */ #define CONFIG_USE_IRQ 1 /* we need IRQ stuff for timer */ +#define CONFIG_TIMER_IRQ #define CONFIG_BOOTCOUNT_LIMIT /* support for bootcount limit */ #define CONFIG_SYS_BOOTCOUNT_ADDR 0x60003000 /* inside qmrg sram */ diff --git a/include/configs/pdnb3.h b/include/configs/pdnb3.h index edaa81b59b..1255f21e8b 100644 --- a/include/configs/pdnb3.h +++ b/include/configs/pdnb3.h @@ -51,6 +51,7 @@ * Misc configuration options */ #define CONFIG_USE_IRQ 1 /* we need IRQ stuff for timer */ +#define CONFIG_TIMER_IRQ #define CONFIG_BOOTCOUNT_LIMIT /* support for bootcount limit */ #define CONFIG_SYS_BOOTCOUNT_ADDR 0x60003000 /* inside qmrg sram */ diff --git a/lib_arm/board.c b/lib_arm/board.c index e3040acdc6..c7768e5289 100644 --- a/lib_arm/board.c +++ b/lib_arm/board.c @@ -266,7 +266,10 @@ init_fnc_t *init_sequence[] = { arch_cpu_init, /* basic arch cpu dependent setup */ #endif board_init, /* basic board dependent setup */ +#if defined(CONFIG_USE_IRQ) interrupt_init, /* set up exceptions */ +#endif + timer_init, /* initialize timer */ env_init, /* initialize environment */ init_baudrate, /* initialze baudrate settings */ serial_init, /* serial communications setup */