Commit 93a0ea501e1eca1ae5d7d2624906b656c765e5e8
Committed by
Stefano Babic
1 parent
4c97f16911
Exists in
v2017.01-smarct4x
and in
37 other branches
arm: mx31: use common timer functions
This patch moves mx31 to the common timer functions added in commit 8dfafdd - Introduce common timer functions <Rob Herring> The (removed) mx31 timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locks the processor. Rather than patch the specific mx31 issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder <andrew.ruder@elecsyscorp.com> Cc: Marek Vasut <marex@denx.de> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: Wolfgang Denk <wd@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Helmut Raiger <helmut.raiger@hale.at>
Showing 2 changed files with 12 additions and 102 deletions Side-by-side Diff
arch/arm/cpu/arm1136/mx31/timer.c
... | ... | @@ -7,9 +7,6 @@ |
7 | 7 | |
8 | 8 | #include <common.h> |
9 | 9 | #include <asm/arch/imx-regs.h> |
10 | -#include <asm/arch/clock.h> | |
11 | -#include <div64.h> | |
12 | -#include <watchdog.h> | |
13 | 10 | #include <asm/io.h> |
14 | 11 | |
15 | 12 | #define TIMER_BASE 0x53f90000 /* General purpose timer 1 */ |
... | ... | @@ -28,57 +25,6 @@ |
28 | 25 | |
29 | 26 | DECLARE_GLOBAL_DATA_PTR; |
30 | 27 | |
31 | -/* | |
32 | - * "time" is measured in 1 / CONFIG_SYS_HZ seconds, | |
33 | - * "tick" is internal timer period | |
34 | - */ | |
35 | - | |
36 | -#ifdef CONFIG_MX31_TIMER_HIGH_PRECISION | |
37 | -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ | |
38 | -static inline unsigned long long tick_to_time(unsigned long long tick) | |
39 | -{ | |
40 | - tick *= CONFIG_SYS_HZ; | |
41 | - do_div(tick, MXC_CLK32); | |
42 | - return tick; | |
43 | -} | |
44 | - | |
45 | -static inline unsigned long long time_to_tick(unsigned long long time) | |
46 | -{ | |
47 | - time *= MXC_CLK32; | |
48 | - do_div(time, CONFIG_SYS_HZ); | |
49 | - return time; | |
50 | -} | |
51 | - | |
52 | -static inline unsigned long long us_to_tick(unsigned long long us) | |
53 | -{ | |
54 | - us = us * MXC_CLK32 + 999999; | |
55 | - do_div(us, 1000000); | |
56 | - return us; | |
57 | -} | |
58 | -#else | |
59 | -/* ~2% error */ | |
60 | -#define TICK_PER_TIME ((MXC_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) | |
61 | -#define US_PER_TICK (1000000 / MXC_CLK32) | |
62 | - | |
63 | -static inline unsigned long long tick_to_time(unsigned long long tick) | |
64 | -{ | |
65 | - do_div(tick, TICK_PER_TIME); | |
66 | - return tick; | |
67 | -} | |
68 | - | |
69 | -static inline unsigned long long time_to_tick(unsigned long long time) | |
70 | -{ | |
71 | - return time * TICK_PER_TIME; | |
72 | -} | |
73 | - | |
74 | -static inline unsigned long long us_to_tick(unsigned long long us) | |
75 | -{ | |
76 | - us += US_PER_TICK - 1; | |
77 | - do_div(us, US_PER_TICK); | |
78 | - return us; | |
79 | -} | |
80 | -#endif | |
81 | - | |
82 | 28 | /* The 32768Hz 32-bit timer overruns in 131072 seconds */ |
83 | 29 | int timer_init(void) |
84 | 30 | { |
85 | 31 | |
... | ... | @@ -95,54 +41,8 @@ |
95 | 41 | return 0; |
96 | 42 | } |
97 | 43 | |
98 | -unsigned long long get_ticks(void) | |
44 | +unsigned long timer_read_counter(void) | |
99 | 45 | { |
100 | - ulong now = GPTCNT; /* current tick value */ | |
101 | - | |
102 | - if (now >= gd->arch.lastinc) /* normal mode (non roll) */ | |
103 | - /* move stamp forward with absolut diff ticks */ | |
104 | - gd->arch.tbl += (now - gd->arch.lastinc); | |
105 | - else /* we have rollover of incrementer */ | |
106 | - gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; | |
107 | - gd->arch.lastinc = now; | |
108 | - return gd->arch.tbl; | |
109 | -} | |
110 | - | |
111 | -ulong get_timer_masked(void) | |
112 | -{ | |
113 | - /* | |
114 | - * get_ticks() returns a long long (64 bit), it wraps in | |
115 | - * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ | |
116 | - * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in | |
117 | - * 5 * 10^6 days - long enough. | |
118 | - */ | |
119 | - return tick_to_time(get_ticks()); | |
120 | -} | |
121 | - | |
122 | -ulong get_timer(ulong base) | |
123 | -{ | |
124 | - return get_timer_masked() - base; | |
125 | -} | |
126 | - | |
127 | -/* delay x useconds AND preserve advance timestamp value */ | |
128 | -void __udelay(unsigned long usec) | |
129 | -{ | |
130 | - unsigned long long tmp; | |
131 | - ulong tmo; | |
132 | - | |
133 | - tmo = us_to_tick(usec); | |
134 | - tmp = get_ticks() + tmo; /* get current timestamp */ | |
135 | - | |
136 | - while (get_ticks() < tmp) /* loop till event */ | |
137 | - /*NOP*/; | |
138 | -} | |
139 | - | |
140 | -/* | |
141 | - * This function is derived from PowerPC code (timebase clock frequency). | |
142 | - * On ARM it returns the number of timer ticks per second. | |
143 | - */ | |
144 | -ulong get_tbclk(void) | |
145 | -{ | |
146 | - return MXC_CLK32; | |
46 | + return GPTCNT; | |
147 | 47 | } |
arch/arm/include/asm/arch-mx31/imx-regs.h
... | ... | @@ -909,10 +909,20 @@ |
909 | 909 | #define MXC_CSPIPERIOD_32KHZ (1 << 15) |
910 | 910 | #define MAX_SPI_BYTES 4 |
911 | 911 | |
912 | + | |
912 | 913 | #define MXC_SPI_BASE_ADDRESSES \ |
913 | 914 | 0x43fa4000, \ |
914 | 915 | 0x50010000, \ |
915 | 916 | 0x53f84000, |
917 | + | |
918 | +/* | |
919 | + * Generic timer support | |
920 | + */ | |
921 | +#ifdef CONFIG_MX31_CLK32 | |
922 | +#define CONFIG_SYS_TIMER_RATE CONFIG_MX31_CLK32 | |
923 | +#else | |
924 | +#define CONFIG_SYS_TIMER_RATE 32768 | |
925 | +#endif | |
916 | 926 | |
917 | 927 | #endif /* __ASM_ARCH_MX31_IMX_REGS_H */ |