]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
52f69f81 VZ |
2 | /* |
3 | * Copyright (C) 2011 Vladimir Zapolskiy <[email protected]> | |
52f69f81 VZ |
4 | */ |
5 | ||
d678a59d | 6 | #include <common.h> |
691d719d | 7 | #include <init.h> |
1045315d | 8 | #include <time.h> |
52f69f81 VZ |
9 | #include <asm/arch/cpu.h> |
10 | #include <asm/arch/clk.h> | |
11 | #include <asm/arch/timer.h> | |
12 | #include <asm/io.h> | |
c05ed00a | 13 | #include <linux/delay.h> |
52f69f81 VZ |
14 | |
15 | static struct timer_regs *timer0 = (struct timer_regs *)TIMER0_BASE; | |
16 | static struct timer_regs *timer1 = (struct timer_regs *)TIMER1_BASE; | |
17 | static struct clk_pm_regs *clk = (struct clk_pm_regs *)CLK_PM_BASE; | |
18 | ||
19 | static void lpc32xx_timer_clock(u32 bit, int enable) | |
20 | { | |
21 | if (enable) | |
22 | setbits_le32(&clk->timclk_ctrl1, bit); | |
23 | else | |
24 | clrbits_le32(&clk->timclk_ctrl1, bit); | |
25 | } | |
26 | ||
27 | static void lpc32xx_timer_reset(struct timer_regs *timer, u32 freq) | |
28 | { | |
29 | writel(TIMER_TCR_COUNTER_RESET, &timer->tcr); | |
30 | writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr); | |
31 | writel(0, &timer->tc); | |
32 | writel(0, &timer->pr); | |
33 | ||
34 | /* Count mode is every rising PCLK edge */ | |
35 | writel(TIMER_CTCR_MODE_TIMER, &timer->ctcr); | |
36 | ||
37 | /* Set prescale counter value */ | |
38 | writel((get_periph_clk_rate() / freq) - 1, &timer->pr); | |
c8aac246 GC |
39 | |
40 | /* Ensure that the counter is not reset when matching TC */ | |
41 | writel(0, &timer->mcr); | |
52f69f81 VZ |
42 | } |
43 | ||
44 | static void lpc32xx_timer_count(struct timer_regs *timer, int enable) | |
45 | { | |
46 | if (enable) | |
47 | writel(TIMER_TCR_COUNTER_ENABLE, &timer->tcr); | |
48 | else | |
49 | writel(TIMER_TCR_COUNTER_DISABLE, &timer->tcr); | |
50 | } | |
51 | ||
52 | int timer_init(void) | |
53 | { | |
54 | lpc32xx_timer_clock(CLK_TIMCLK_TIMER0, 1); | |
55 | lpc32xx_timer_reset(timer0, CONFIG_SYS_HZ); | |
56 | lpc32xx_timer_count(timer0, 1); | |
57 | ||
58 | return 0; | |
59 | } | |
60 | ||
61 | ulong get_timer(ulong base) | |
62 | { | |
63 | return readl(&timer0->tc) - base; | |
64 | } | |
65 | ||
66 | void __udelay(unsigned long usec) | |
67 | { | |
68 | lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 1); | |
69 | lpc32xx_timer_reset(timer1, CONFIG_SYS_HZ * 1000); | |
70 | lpc32xx_timer_count(timer1, 1); | |
71 | ||
72 | while (readl(&timer1->tc) < usec) | |
73 | /* NOP */; | |
74 | ||
75 | lpc32xx_timer_count(timer1, 0); | |
76 | lpc32xx_timer_clock(CLK_TIMCLK_TIMER1, 0); | |
77 | } | |
78 | ||
79 | unsigned long long get_ticks(void) | |
80 | { | |
81 | return get_timer(0); | |
82 | } | |
83 | ||
84 | ulong get_tbclk(void) | |
85 | { | |
86 | return CONFIG_SYS_HZ; | |
87 | } |