]>
Commit | Line | Data |
---|---|---|
98250e8e JS |
1 | /* |
2 | * (C) Copyright 2002 | |
3 | * Lineo, Inc. <www.lineo.com> | |
4 | * Bernhard Kuhn <bkuhn@lineo.com> | |
5 | * | |
6 | * (C) Copyright 2002 | |
7 | * Sysgo Real-Time Solutions, GmbH <www.elinos.com> | |
8 | * Marius Groeger <mgroeger@sysgo.de> | |
9 | * | |
10 | * (C) Copyright 2002 | |
11 | * Sysgo Real-Time Solutions, GmbH <www.elinos.com> | |
12 | * Alex Zuepke <azu@sysgo.de> | |
13 | * | |
1a459660 | 14 | * SPDX-License-Identifier: GPL-2.0+ |
98250e8e JS |
15 | */ |
16 | ||
17 | #include <common.h> | |
18 | ||
80733994 | 19 | #include <asm/io.h> |
a429db7e | 20 | #include <asm/arch/hardware.h> |
98250e8e JS |
21 | #include <asm/arch/at91_tc.h> |
22 | #include <asm/arch/at91_pmc.h> | |
23 | ||
a429db7e AB |
24 | DECLARE_GLOBAL_DATA_PTR; |
25 | ||
98250e8e JS |
26 | /* the number of clocks per CONFIG_SYS_HZ */ |
27 | #define TIMER_LOAD_VAL (CONFIG_SYS_HZ_CLOCK/CONFIG_SYS_HZ) | |
28 | ||
98250e8e JS |
29 | int timer_init(void) |
30 | { | |
80733994 JS |
31 | at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; |
32 | at91_pmc_t *pmc = (at91_pmc_t *) ATMEL_BASE_PMC; | |
98250e8e JS |
33 | |
34 | /* enables TC1.0 clock */ | |
80733994 | 35 | writel(1 << ATMEL_ID_TC0, &pmc->pcer); /* enable clock */ |
98250e8e JS |
36 | |
37 | writel(0, &tc->bcr); | |
38 | writel(AT91_TC_BMR_TC0XC0S_NONE | AT91_TC_BMR_TC1XC1S_NONE | | |
39 | AT91_TC_BMR_TC2XC2S_NONE , &tc->bmr); | |
40 | ||
41 | writel(AT91_TC_CCR_CLKDIS, &tc->tc[0].ccr); | |
42 | /* set to MCLK/2 and restart the timer | |
43 | when the value in TC_RC is reached */ | |
44 | writel(AT91_TC_CMR_TCCLKS_CLOCK1 | AT91_TC_CMR_CPCTRG, &tc->tc[0].cmr); | |
45 | ||
16263087 | 46 | writel(0xFFFFFFFF, &tc->tc[0].idr); /* disable interrupts */ |
98250e8e JS |
47 | writel(TIMER_LOAD_VAL, &tc->tc[0].rc); |
48 | ||
49 | writel(AT91_TC_CCR_SWTRG | AT91_TC_CCR_CLKEN, &tc->tc[0].ccr); | |
582601da | 50 | gd->arch.lastinc = 0; |
66ee6923 | 51 | gd->arch.tbl = 0; |
98250e8e JS |
52 | |
53 | return 0; | |
54 | } | |
55 | ||
56 | /* | |
57 | * timer without interrupts | |
58 | */ | |
98250e8e JS |
59 | ulong get_timer(ulong base) |
60 | { | |
61 | return get_timer_masked() - base; | |
62 | } | |
63 | ||
98250e8e JS |
64 | void __udelay(unsigned long usec) |
65 | { | |
66 | udelay_masked(usec); | |
67 | } | |
68 | ||
98250e8e JS |
69 | ulong get_timer_raw(void) |
70 | { | |
80733994 | 71 | at91_tc_t *tc = (at91_tc_t *) ATMEL_BASE_TC; |
98250e8e JS |
72 | u32 now; |
73 | ||
74 | now = readl(&tc->tc[0].cv) & 0x0000ffff; | |
75 | ||
582601da | 76 | if (now >= gd->arch.lastinc) { |
98250e8e | 77 | /* normal mode */ |
582601da | 78 | gd->arch.tbl += now - gd->arch.lastinc; |
98250e8e JS |
79 | } else { |
80 | /* we have an overflow ... */ | |
582601da | 81 | gd->arch.tbl += now + TIMER_LOAD_VAL - gd->arch.lastinc; |
98250e8e | 82 | } |
582601da | 83 | gd->arch.lastinc = now; |
98250e8e | 84 | |
66ee6923 | 85 | return gd->arch.tbl; |
98250e8e JS |
86 | } |
87 | ||
88 | ulong get_timer_masked(void) | |
89 | { | |
90 | return get_timer_raw()/TIMER_LOAD_VAL; | |
91 | } | |
92 | ||
93 | void udelay_masked(unsigned long usec) | |
94 | { | |
95 | u32 tmo; | |
96 | u32 endtime; | |
97 | signed long diff; | |
98 | ||
99 | tmo = CONFIG_SYS_HZ_CLOCK / 1000; | |
100 | tmo *= usec; | |
101 | tmo /= 1000; | |
102 | ||
103 | endtime = get_timer_raw() + tmo; | |
104 | ||
105 | do { | |
106 | u32 now = get_timer_raw(); | |
107 | diff = endtime - now; | |
108 | } while (diff >= 0); | |
109 | } | |
110 | ||
111 | /* | |
112 | * This function is derived from PowerPC code (read timebase as long long). | |
113 | * On ARM it just returns the timer value. | |
114 | */ | |
115 | unsigned long long get_ticks(void) | |
116 | { | |
117 | return get_timer(0); | |
118 | } | |
119 | ||
120 | /* | |
121 | * This function is derived from PowerPC code (timebase clock frequency). | |
122 | * On ARM it returns the number of timer ticks per second. | |
123 | */ | |
124 | ulong get_tbclk(void) | |
125 | { | |
126 | return CONFIG_SYS_HZ; | |
127 | } |