2 * Copyright (C) 2012 Altera Corporation <www.altera.com>
4 * SPDX-License-Identifier: GPL-2.0+
9 #include <asm/arch/timer.h>
11 DECLARE_GLOBAL_DATA_PTR;
13 static const struct socfpga_timer *timer_base = (void *)CONFIG_SYS_TIMERBASE;
16 * Timer initialization
20 writel(TIMER_LOAD_VAL, &timer_base->load_val);
21 writel(TIMER_LOAD_VAL, &timer_base->curr_val);
22 writel(readl(&timer_base->ctrl) | 0x3, &timer_base->ctrl);
26 static u32 read_timer(void)
28 return readl(&timer_base->curr_val);
34 void __udelay(unsigned long usec)
36 unsigned long now, last;
38 * get the tmo value based on timer clock speed
39 * tmo = delay required / period of timer clock
41 long tmo = usec * CONFIG_TIMER_CLOCK_KHZ / 1000;
47 /* normal mode (non roll) */
50 /* we have overflow of the count down timer */
51 tmo -= TIMER_LOAD_VAL - last + now;
59 ulong get_timer(ulong base)
61 return get_timer_masked() - base;
65 * Timer : get the time difference
66 * Unit of tick is based on the CONFIG_SYS_HZ
68 ulong get_timer_masked(void)
70 /* current tick value */
71 ulong now = read_timer() / (CONFIG_TIMER_CLOCK_KHZ/CONFIG_SYS_HZ);
72 if (gd->arch.lastinc >= now) {
73 /* normal mode (non roll) */
74 /* move stamp forward with absolute diff ticks */
75 gd->arch.tbl += gd->arch.lastinc - now;
77 /* we have overflow of the count down timer */
78 gd->arch.tbl += TIMER_LOAD_VAL - gd->arch.lastinc + now;
80 gd->arch.lastinc = now;
87 void reset_timer(void)
89 /* capture current decrementer value time */
90 gd->arch.lastinc = read_timer() /
91 (CONFIG_TIMER_CLOCK_KHZ / CONFIG_SYS_HZ);
92 /* start "advancing" time stamp from 0 */