diff options
author | Andrew Ruder <andrew.ruder@elecsyscorp.com> | 2014-08-12 09:26:00 -0500 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2014-09-16 12:51:46 +0200 |
commit | 93a0ea501e1eca1ae5d7d2624906b656c765e5e8 (patch) | |
tree | bb92988867941e0b54333a825ff5bea04e6e6bc5 /arch | |
parent | 4c97f16911e229f6d5bbea5bee52449916e5fa92 (diff) | |
download | u-boot-imx-93a0ea501e1eca1ae5d7d2624906b656c765e5e8.zip u-boot-imx-93a0ea501e1eca1ae5d7d2624906b656c765e5e8.tar.gz u-boot-imx-93a0ea501e1eca1ae5d7d2624906b656c765e5e8.tar.bz2 |
arm: mx31: use common timer functions
This patch moves mx31 to the common timer functions added in commit
8dfafdd - Introduce common timer functions <Rob Herring>
The (removed) mx31 timer code (specifically __udelay()) could deadlock at
the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value
cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed
the 32-bit boundary, the while condition became unconditionally true and
locks the processor. Rather than patch the specific mx31 issues, simply
move everything over to the common code.
Signed-off-by: Andrew Ruder <andrew.ruder@elecsyscorp.com>
Cc: Marek Vasut <marex@denx.de>
Cc: Linus Walleij <linus.walleij@linaro.org>
Cc: Wolfgang Denk <wd@denx.de>
Cc: Fabio Estevam <fabio.estevam@freescale.com>
Cc: Helmut Raiger <helmut.raiger@hale.at>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/cpu/arm1136/mx31/timer.c | 104 | ||||
-rw-r--r-- | arch/arm/include/asm/arch-mx31/imx-regs.h | 10 |
2 files changed, 12 insertions, 102 deletions
diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c index f111242..3a81ce4 100644 --- a/arch/arm/cpu/arm1136/mx31/timer.c +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -7,9 +7,6 @@ #include <common.h> #include <asm/arch/imx-regs.h> -#include <asm/arch/clock.h> -#include <div64.h> -#include <watchdog.h> #include <asm/io.h> #define TIMER_BASE 0x53f90000 /* General purpose timer 1 */ @@ -28,57 +25,6 @@ DECLARE_GLOBAL_DATA_PTR; -/* - * "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, MXC_CLK32); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - time *= MXC_CLK32; - do_div(time, CONFIG_SYS_HZ); - return time; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * MXC_CLK32 + 999999; - do_div(us, 1000000); - return us; -} -#else -/* ~2% error */ -#define TICK_PER_TIME ((MXC_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) -#define US_PER_TICK (1000000 / MXC_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) { @@ -95,53 +41,7 @@ int timer_init(void) return 0; } -unsigned long long get_ticks(void) -{ - ulong now = GPTCNT; /* current tick value */ - - if (now >= gd->arch.lastinc) /* normal mode (non roll) */ - /* move stamp forward with absolut diff ticks */ - gd->arch.tbl += (now - gd->arch.lastinc); - else /* we have rollover of incrementer */ - gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; - gd->arch.lastinc = now; - return gd->arch.tbl; -} - -ulong get_timer_masked(void) -{ - /* - * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / MXC_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; -} - -/* delay x useconds AND preserve advance timestamp 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*/; -} - -/* - * 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) +unsigned long timer_read_counter(void) { - return MXC_CLK32; + return GPTCNT; } diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h index f23350e..71ebd24 100644 --- a/arch/arm/include/asm/arch-mx31/imx-regs.h +++ b/arch/arm/include/asm/arch-mx31/imx-regs.h @@ -909,9 +909,19 @@ struct esdc_regs { #define MXC_CSPIPERIOD_32KHZ (1 << 15) #define MAX_SPI_BYTES 4 + #define MXC_SPI_BASE_ADDRESSES \ 0x43fa4000, \ 0x50010000, \ 0x53f84000, +/* + * Generic timer support + */ +#ifdef CONFIG_MX31_CLK32 +#define CONFIG_SYS_TIMER_RATE CONFIG_MX31_CLK32 +#else +#define CONFIG_SYS_TIMER_RATE 32768 +#endif + #endif /* __ASM_ARCH_MX31_IMX_REGS_H */ |