[U-Boot] [PATCH 1/9] ARM: add common timer functions

Rob Herring
2013-09-08T20:12:46Z

Many ARM platforms duplicate pretty much the same timer code yet they
all have a 32-bit freerunning counter register. Create a common
implementation that simply requires 3 defines to add timer support:

CONFIG_SYS_TIMER_RATE - Clock rate of the timer counter
CONFIG_SYS_TIMER_COUNTER - Address of 32-bit counter
CONFIG_SYS_TIMER_COUNTS_DOWN - Define if counter counts down

Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
arch/arm/lib/Makefile | 2 +-
arch/arm/lib/time.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 1 deletion(-)
create mode 100644 arch/arm/lib/time.c

diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 4e78723..0bf5877 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -38,7 +38,7 @@ else
COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o
endif

-COBJS-y += interrupts.o
+COBJS-y += interrupts.o time.o
COBJS-y += reset.o

COBJS-y += cache.o
diff --git a/arch/arm/lib/time.c b/arch/arm/lib/time.c
new file mode 100644
index 0000000..0ec8ded
--- /dev/null
+++ b/arch/arm/lib/time.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2013 Calxeda, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <div64.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_SYS_TIMER_RATE
+ulong notrace get_tbclk(void)
+{
+ return CONFIG_SYS_TIMER_RATE;
+}
+#endif
+
+#ifdef CONFIG_SYS_TIMER_COUNTER
+unsigned long notrace timer_read_counter(void)
+{
+#ifdef CONFIG_SYS_TIMER_COUNTS_DOWN
+ return ~readl(CONFIG_SYS_TIMER_COUNTER);
+#else
+ return readl(CONFIG_SYS_TIMER_COUNTER);
+#endif
+}
+#endif
+
+unsigned long long __weak notrace get_ticks(void)
+{
+ unsigned long now = timer_read_counter();
+
+ /* increment tbu if tbl has rolled over */
+ if (now < gd->arch.tbl)
+ gd->arch.tbu++;
+ gd->arch.tbl = now;
+ return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl;
+}
+
+static unsigned long long notrace tick_to_time(unsigned long long tick)
+{
+ unsigned int div = get_tbclk();
+
+ tick *= CONFIG_SYS_HZ;
+ do_div(tick, div);
+ return tick;
+}
+
+ulong __weak get_timer(ulong base)
+{
+ return tick_to_time(get_ticks()) - base;
+}
+
+unsigned long __weak notrace timer_get_us(void)
+{
+ return tick_to_time(get_ticks() * 1000);
+}
--
1.8.1.2