xref: /rk3399_rockchip-uboot/arch/arm/cpu/arm926ejs/lpc32xx/timer.c (revision 52f69f818c016a05fb81cfc51b42eecfb7240a6c)
1*52f69f81SVladimir Zapolskiy /*
2*52f69f81SVladimir Zapolskiy  * Copyright (C) 2011 Vladimir Zapolskiy <vz@mleia.com>
3*52f69f81SVladimir Zapolskiy  *
4*52f69f81SVladimir Zapolskiy  * This program is free software; you can redistribute it and/or
5*52f69f81SVladimir Zapolskiy  * modify it under the terms of the GNU General Public License
6*52f69f81SVladimir Zapolskiy  * as published by the Free Software Foundation; either version 2
7*52f69f81SVladimir Zapolskiy  * of the License, or (at your option) any later version.
8*52f69f81SVladimir Zapolskiy  *
9*52f69f81SVladimir Zapolskiy  * This program is distributed in the hope that it will be useful,
10*52f69f81SVladimir Zapolskiy  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11*52f69f81SVladimir Zapolskiy  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12*52f69f81SVladimir Zapolskiy  * GNU General Public License for more details.
13*52f69f81SVladimir Zapolskiy  *
14*52f69f81SVladimir Zapolskiy  * You should have received a copy of the GNU General Public License
15*52f69f81SVladimir Zapolskiy  * along with this program; if not, write to the Free Software
16*52f69f81SVladimir Zapolskiy  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17*52f69f81SVladimir Zapolskiy  * MA  02110-1301, USA.
18*52f69f81SVladimir Zapolskiy  */
19*52f69f81SVladimir Zapolskiy 
20*52f69f81SVladimir Zapolskiy #include <common.h>
21*52f69f81SVladimir Zapolskiy #include <asm/arch/cpu.h>
22*52f69f81SVladimir Zapolskiy #include <asm/arch/clk.h>
23*52f69f81SVladimir Zapolskiy #include <asm/arch/timer.h>
24*52f69f81SVladimir Zapolskiy #include <asm/io.h>
25*52f69f81SVladimir Zapolskiy 
26*52f69f81SVladimir Zapolskiy static struct timer_regs  *timer0 = (struct timer_regs *)TIMER0_BASE;
27*52f69f81SVladimir Zapolskiy static struct timer_regs  *timer1 = (struct timer_regs *)TIMER1_BASE;
28*52f69f81SVladimir Zapolskiy static struct clk_pm_regs *clk    = (struct clk_pm_regs *)CLK_PM_BASE;
29*52f69f81SVladimir Zapolskiy 
30*52f69f81SVladimir Zapolskiy static void lpc32xx_timer_clock(u32 bit, int enable)
31*52f69f81SVladimir Zapolskiy {
32*52f69f81SVladimir Zapolskiy 	if (enable)
33*52f69f81SVladimir Zapolskiy 		setbits_le32(&clk->timclk_ctrl1, bit);
34*52f69f81SVladimir Zapolskiy 	else
35*52f69f81SVladimir Zapolskiy 		clrbits_le32(&clk->timclk_ctrl1, bit);
36*52f69f81SVladimir Zapolskiy }
37*52f69f81SVladimir Zapolskiy 
38*52f69f81SVladimir Zapolskiy static void lpc32xx_timer_reset(struct timer_regs *timer, u32 freq)
39*52f69f81SVladimir Zapolskiy {
40*52f69f81SVladimir Zapolskiy 	writel(TIMER_TCR_COUNTER_RESET,   &timer->tcr);
41*52f69f81SVladimir Zapolskiy 	writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr);
42*52f69f81SVladimir Zapolskiy 	writel(0, &timer->tc);
43*52f69f81SVladimir Zapolskiy 	writel(0, &timer->pr);
44*52f69f81SVladimir Zapolskiy 
45*52f69f81SVladimir Zapolskiy 	/* Count mode is every rising PCLK edge */
46*52f69f81SVladimir Zapolskiy 	writel(TIMER_CTCR_MODE_TIMER, &timer->ctcr);
47*52f69f81SVladimir Zapolskiy 
48*52f69f81SVladimir Zapolskiy 	/* Set prescale counter value */
49*52f69f81SVladimir Zapolskiy 	writel((get_periph_clk_rate() / freq) - 1, &timer->pr);
50*52f69f81SVladimir Zapolskiy }
51*52f69f81SVladimir Zapolskiy 
52*52f69f81SVladimir Zapolskiy static void lpc32xx_timer_count(struct timer_regs *timer, int enable)
53*52f69f81SVladimir Zapolskiy {
54*52f69f81SVladimir Zapolskiy 	if (enable)
55*52f69f81SVladimir Zapolskiy 		writel(TIMER_TCR_COUNTER_ENABLE,  &timer->tcr);
56*52f69f81SVladimir Zapolskiy 	else
57*52f69f81SVladimir Zapolskiy 		writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr);
58*52f69f81SVladimir Zapolskiy }
59*52f69f81SVladimir Zapolskiy 
60*52f69f81SVladimir Zapolskiy int timer_init(void)
61*52f69f81SVladimir Zapolskiy {
62*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_clock(CLK_TIMCLK_TIMER0, 1);
63*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_reset(timer0, CONFIG_SYS_HZ);
64*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_count(timer0, 1);
65*52f69f81SVladimir Zapolskiy 
66*52f69f81SVladimir Zapolskiy 	return 0;
67*52f69f81SVladimir Zapolskiy }
68*52f69f81SVladimir Zapolskiy 
69*52f69f81SVladimir Zapolskiy ulong get_timer(ulong base)
70*52f69f81SVladimir Zapolskiy {
71*52f69f81SVladimir Zapolskiy 	return readl(&timer0->tc) - base;
72*52f69f81SVladimir Zapolskiy }
73*52f69f81SVladimir Zapolskiy 
74*52f69f81SVladimir Zapolskiy void __udelay(unsigned long usec)
75*52f69f81SVladimir Zapolskiy {
76*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 1);
77*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_reset(timer1, CONFIG_SYS_HZ * 1000);
78*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_count(timer1, 1);
79*52f69f81SVladimir Zapolskiy 
80*52f69f81SVladimir Zapolskiy 	while (readl(&timer1->tc) < usec)
81*52f69f81SVladimir Zapolskiy 		/* NOP */;
82*52f69f81SVladimir Zapolskiy 
83*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_count(timer1, 0);
84*52f69f81SVladimir Zapolskiy 	lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 0);
85*52f69f81SVladimir Zapolskiy }
86*52f69f81SVladimir Zapolskiy 
87*52f69f81SVladimir Zapolskiy unsigned long long get_ticks(void)
88*52f69f81SVladimir Zapolskiy {
89*52f69f81SVladimir Zapolskiy 	return get_timer(0);
90*52f69f81SVladimir Zapolskiy }
91*52f69f81SVladimir Zapolskiy 
92*52f69f81SVladimir Zapolskiy ulong get_tbclk(void)
93*52f69f81SVladimir Zapolskiy {
94*52f69f81SVladimir Zapolskiy 	return CONFIG_SYS_HZ;
95*52f69f81SVladimir Zapolskiy }
96