On Tuesday, August 12, 2014 at 04:26:00 PM, andrew.ru...@elecsyscorp.com wrote: > From: Andrew Ruder <andrew.ru...@elecsyscorp.com> > > 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.ru...@elecsyscorp.com> > Cc: Marek Vasut <ma...@denx.de> > Cc: Linus Walleij <linus.wall...@linaro.org> > Cc: Wolfgang Denk <w...@denx.de> > Cc: Fabio Estevam <fabio.este...@freescale.com> > Cc: Helmut Raiger <helmut.rai...@hale.at>
+CC Stefano > --- > > This patch has been COMPILE tested only. The situation isn't quite as > bad on mx31 as 32-bit rollover occurs in about a day and a half. > > Before patch: > Configuring for qong board... > 456 -rw-r--r-- 1 andy andy 463236 Aug 12 08:36 u-boot.bin > > After patch: > Configuring for qong board... > 456 -rw-r--r-- 1 andy andy 463248 Aug 12 08:38 u-boot.bin > > arch/arm/cpu/arm1136/mx31/timer.c | 104 > +----------------------------- 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 */ _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot