3 * Ingenic Semiconductor, <jlwei@ingenic.cn>
5 * SPDX-License-Identifier: GPL-2.0+
12 #include <asm/jz4740.h>
15 #define TIMER_FDATA 0xffff /* Timer full data value */
17 DECLARE_GLOBAL_DATA_PTR;
19 static struct jz4740_tcu *tcu = (struct jz4740_tcu *)JZ4740_TCU_BASE;
21 void reset_timer_masked(void)
24 gd->arch.lastinc = readl(&tcu->tcnt0);
28 ulong get_timer_masked(void)
30 ulong now = readl(&tcu->tcnt0);
32 if (gd->arch.lastinc <= now)
33 gd->arch.tbl += now - gd->arch.lastinc; /* normal mode */
35 /* we have an overflow ... */
36 gd->arch.tbl += TIMER_FDATA + now - gd->arch.lastinc;
39 gd->arch.lastinc = now;
44 void udelay_masked(unsigned long usec)
57 tmo = usec * CONFIG_SYS_HZ;
63 endtime = get_timer_masked() + tmo;
66 ulong now = get_timer_masked();
73 writel(TCU_TCSR_PRESCALE256 | TCU_TCSR_EXT_EN, &tcu->tcsr0);
75 writel(0, &tcu->tcnt0);
76 writel(0, &tcu->tdhr0);
77 writel(TIMER_FDATA, &tcu->tdfr0);
80 writel((1 << TIMER_CHAN) | (1 << (TIMER_CHAN + 16)), &tcu->tmsr);
81 writel(1 << TIMER_CHAN, &tcu->tscr); /* enable timer clock */
82 writeb(1 << TIMER_CHAN, &tcu->tesr); /* start counting up */
90 void reset_timer(void)
95 ulong get_timer(ulong base)
97 return get_timer_masked() - base;
100 void set_timer(ulong t)
105 void __udelay(unsigned long usec)
112 tmo *= CONFIG_SYS_HZ;
116 tmo = usec * CONFIG_SYS_HZ;
122 /* check for rollover during this delay */
124 if ((tmp + tmo) < tmp)
125 reset_timer_masked(); /* timer would roll over */
129 while (get_timer_masked() < tmo)
134 * This function is derived from PowerPC code (read timebase as long long).
135 * On MIPS it just returns the timer value.
137 unsigned long long get_ticks(void)
143 * This function is derived from PowerPC code (timebase clock frequency).
144 * On MIPS it returns the number of timer ticks per second.
146 ulong get_tbclk(void)
148 return CONFIG_SYS_HZ;