diff options
author | Stefan Agner <stefan.agner@toradex.com> | 2015-07-07 09:03:47 +0200 |
---|---|---|
committer | Stefan Agner <stefan.agner@toradex.com> | 2015-07-07 09:03:47 +0200 |
commit | fc69db24720b0d5aed7b04a70ddc56a0162cb7f5 (patch) | |
tree | ff4a8db1966b7e62a9651cf8ad37a180894fdd09 | |
parent | f3a9a52388e47475faddf581e2510be852d6e5fb (diff) |
arm: vf610: support global timer
Add support for ARM global timer. This allows to save the platform
wide PIT timer for other purposes such as MQX on the secondary
Cortex-M4 core.
-rw-r--r-- | arch/arm/cpu/armv7/vf610/Makefile | 3 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/vf610/global_timer.c | 87 | ||||
-rw-r--r-- | include/configs/colibri_vf.h | 1 |
3 files changed, 91 insertions, 0 deletions
diff --git a/arch/arm/cpu/armv7/vf610/Makefile b/arch/arm/cpu/armv7/vf610/Makefile index 68cb756d674..ad22fc64ae7 100644 --- a/arch/arm/cpu/armv7/vf610/Makefile +++ b/arch/arm/cpu/armv7/vf610/Makefile @@ -5,4 +5,7 @@ # obj-y += generic.o +ifneq ($(CONFIG_SYS_GLOBAL_TIMER),y) obj-y += timer.o +endif +obj-$(CONFIG_SYS_GLOBAL_TIMER) += global_timer.o diff --git a/arch/arm/cpu/armv7/vf610/global_timer.c b/arch/arm/cpu/armv7/vf610/global_timer.c new file mode 100644 index 00000000000..db5c510b641 --- /dev/null +++ b/arch/arm/cpu/armv7/vf610/global_timer.c @@ -0,0 +1,87 @@ +/* + * (C) Copyright 2015 Toradex AG + * (C) Copyright 2012 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * (C) Copyright 2012 Renesas Solutions Corp. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <div64.h> +#include <asm/io.h> +#include <asm/arch-armv7/globaltimer.h> +#include <asm/arch-vf610/clock.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct globaltimer *global_timer = \ + (struct globaltimer *)(CA5SCU_BASE_ADDR + 0x200); + +#define CLK2MHZ(clk) (clk / 1000 / 1000) +static u64 get_cpu_global_timer(void) +{ + u32 low, high; + u64 timer; + + u32 old = readl(&global_timer->cnt_h); + while (1) { + low = readl(&global_timer->cnt_l); + high = readl(&global_timer->cnt_h); + if (old == high) + break; + else + old = high; + } + + timer = high; + return (u64)((timer << 32) | low); +} + +static u64 get_time_us(void) +{ + u64 timer = get_cpu_global_timer(); + + do_div(timer, CLK2MHZ(mxc_get_clock(MXC_BUS_CLK))); + return timer; +} + +static ulong get_time_ms(void) +{ + u64 us = get_time_us(); + + do_div(us, 1000); + return us; +} + +int timer_init(void) +{ + writel(0x01, &global_timer->ctl); + return 0; +} + +void __udelay(unsigned long usec) +{ + u64 start, current; + u64 wait; + + start = get_cpu_global_timer(); + wait = (u64)((usec * CLK2MHZ(mxc_get_clock(MXC_BUS_CLK))) >> 2); + do { + current = get_cpu_global_timer(); + } while ((current - start) < wait); +} + +ulong get_timer(ulong base) +{ + return get_time_ms() - base; +} + +unsigned long long get_ticks(void) +{ + return get_cpu_global_timer(); +} + +ulong get_tbclk(void) +{ + return (ulong)(mxc_get_clock(MXC_BUS_CLK) >> 2); +} diff --git a/include/configs/colibri_vf.h b/include/configs/colibri_vf.h index 1cbe08d2b96..e3e70cf1a81 100644 --- a/include/configs/colibri_vf.h +++ b/include/configs/colibri_vf.h @@ -22,6 +22,7 @@ #define CONFIG_USE_ARCH_MEMSET #define CONFIG_SYS_GENERIC_BOARD +#define CONFIG_SYS_GLOBAL_TIMER #define CONFIG_ARCH_CPU_INIT #define CONFIG_ARCH_MISC_INIT #define CONFIG_DISPLAY_CPUINFO |