X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=arch%2Farm%2Fimx-common%2Ftimer.c;h=4943a2a307a9338b203572333c564d4cb0253013;hb=HEAD;hp=65ef60bf2edb0a115d7bc48b1eb35dffa0b41901;hpb=c88eaea0a0a809884388c3a5727d960bac0b0ced;p=karo-tx-uboot.git diff --git a/arch/arm/imx-common/timer.c b/arch/arm/imx-common/timer.c index 65ef60bf2e..4943a2a307 100644 --- a/arch/arm/imx-common/timer.c +++ b/arch/arm/imx-common/timer.c @@ -42,10 +42,11 @@ DECLARE_GLOBAL_DATA_PTR; static inline int gpt_has_clk_source_osc(void) { -#if defined(CONFIG_MX6) +#if defined(CONFIG_ARCH_MX6) if (((is_cpu_type(MXC_CPU_MX6Q) || is_cpu_type(MXC_CPU_MX6D)) && - (is_soc_rev(CHIP_REV_1_0) > 0)) || is_cpu_type(MXC_CPU_MX6DL) || - is_cpu_type(MXC_CPU_MX6SOLO) || is_cpu_type(MXC_CPU_MX6SX)) + (soc_rev() > CHIP_REV_1_0)) || is_cpu_type(MXC_CPU_MX6DL) || + is_cpu_type(MXC_CPU_MX6SOLO) || is_cpu_type(MXC_CPU_MX6SX) || + is_cpu_type(MXC_CPU_MX6UL)) return 1; return 0; @@ -75,6 +76,15 @@ static inline unsigned long long tick_to_time(unsigned long long tick) return tick; } +static inline unsigned long long time_to_tick(unsigned long time) +{ + unsigned long long ticks = (unsigned long long)time; + + ticks *= gpt_get_clk(); + do_div(ticks, CONFIG_SYS_HZ); + return ticks; +} + static inline unsigned long long us_to_tick(unsigned long long usec) { ulong gpt_clk = gpt_get_clk(); @@ -103,10 +113,11 @@ int timer_init(void) if (gpt_has_clk_source_osc()) { i |= GPTCR_CLKSOURCE_OSC | GPTCR_TEN; - /* For DL/S, SX, set 24Mhz OSC Enable bit and prescaler */ + /* For DL/S, SX, UL, set 24Mhz OSC Enable bit and prescaler */ if (is_cpu_type(MXC_CPU_MX6DL) || is_cpu_type(MXC_CPU_MX6SOLO) || - is_cpu_type(MXC_CPU_MX6SX)) { + is_cpu_type(MXC_CPU_MX6SX) || + is_cpu_type(MXC_CPU_MX6UL)) { i |= GPTCR_24MEN; /* Produce 3Mhz clock */ @@ -125,6 +136,7 @@ int timer_init(void) gd->arch.tbl = __raw_readl(&cur_gpt->counter); gd->arch.tbu = 0; + gd->arch.timer_rate_hz = gpt_get_clk(); return 0; } @@ -152,20 +164,24 @@ ulong get_timer_masked(void) ulong get_timer(ulong base) { - return get_timer_masked() - base; + return tick_to_time(get_ticks() - time_to_tick(base)); } /* delay x useconds AND preserve advance timstamp value */ void __udelay(unsigned long usec) { - unsigned long long tmp; - ulong tmo; + unsigned long start = __raw_readl(&cur_gpt->counter); + unsigned long ticks; - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ + if (usec == 0) + return; - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; + ticks = us_to_tick(usec); + if (ticks == 0) + ticks++; + + while (__raw_readl(&cur_gpt->counter) - start < ticks) + /* loop till event */; } /* @@ -176,3 +192,20 @@ ulong get_tbclk(void) { return gpt_get_clk(); } + +/* + * This function is intended for SHORT delays only. + * It will overflow at around 10 seconds @ 400MHz, + * or 20 seconds @ 200MHz. + */ +unsigned long usec2ticks(unsigned long usec) +{ + ulong ticks; + + if (usec < 1000) + ticks = ((usec * (get_tbclk()/1000)) + 500) / 1000; + else + ticks = ((usec / 10) * (get_tbclk() / 100000)); + + return ticks; +}