1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#undef DEBUG_TIMER
19
20#include <linux/errno.h>
21#include <linux/init.h>
22#include <linux/module.h>
23#include <linux/sched.h>
24#include <linux/kernel.h>
25#include <linux/param.h>
26#include <linux/string.h>
27#include <linux/mm.h>
28#include <linux/interrupt.h>
29#include <linux/profile.h>
30
31#include <asm/io.h>
32#include <asm/m32r.h>
33
34#include <asm/hw_irq.h>
35
36#ifdef CONFIG_SMP
37extern void send_IPI_allbutself(int, int);
38extern void smp_local_timer_interrupt(void);
39#endif
40
41#define TICK_SIZE (tick_nsec / 1000)
42
43
44
45
46
47
48#define USECS_PER_JIFFY (1000000/HZ)
49
50static unsigned long latch;
51
52static unsigned long do_gettimeoffset(void)
53{
54 unsigned long elapsed_time = 0;
55
56#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
57 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
58 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
59#ifndef CONFIG_SMP
60
61 unsigned long count;
62
63
64 count = inl(M32R_MFT2CUT_PORTL);
65
66 if (inl(M32R_ICU_CR18_PORTL) & 0x00000100)
67 count = 0;
68
69 count = (latch - count) * TICK_SIZE;
70 elapsed_time = (count + latch / 2) / latch;
71
72
73#else
74 unsigned long count;
75 static unsigned long p_jiffies = -1;
76 static unsigned long p_count = 0;
77
78
79 count = inl(M32R_MFT2CUT_PORTL);
80
81 if (jiffies == p_jiffies && count > p_count)
82 count = 0;
83
84 p_jiffies = jiffies;
85 p_count = count;
86
87 count = (latch - count) * TICK_SIZE;
88 elapsed_time = (count + latch / 2) / latch;
89
90#endif
91#elif defined(CONFIG_CHIP_M32310)
92#warning do_gettimeoffse not implemented
93#else
94#error no chip configuration
95#endif
96
97 return elapsed_time;
98}
99
100
101
102
103void do_gettimeofday(struct timeval *tv)
104{
105 unsigned long seq;
106 unsigned long usec, sec;
107 unsigned long max_ntp_tick = tick_usec - tickadj;
108
109 do {
110 seq = read_seqbegin(&xtime_lock);
111
112 usec = do_gettimeoffset();
113
114
115
116
117
118
119 if (unlikely(time_adjust < 0))
120 usec = min(usec, max_ntp_tick);
121
122 sec = xtime.tv_sec;
123 usec += (xtime.tv_nsec / 1000);
124 } while (read_seqretry(&xtime_lock, seq));
125
126 while (usec >= 1000000) {
127 usec -= 1000000;
128 sec++;
129 }
130
131 tv->tv_sec = sec;
132 tv->tv_usec = usec;
133}
134
135EXPORT_SYMBOL(do_gettimeofday);
136
137int do_settimeofday(struct timespec *tv)
138{
139 time_t wtm_sec, sec = tv->tv_sec;
140 long wtm_nsec, nsec = tv->tv_nsec;
141
142 if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
143 return -EINVAL;
144
145 write_seqlock_irq(&xtime_lock);
146
147
148
149
150
151
152 nsec -= do_gettimeoffset() * NSEC_PER_USEC;
153
154 wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
155 wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
156
157 set_normalized_timespec(&xtime, sec, nsec);
158 set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec);
159
160 ntp_clear();
161 write_sequnlock_irq(&xtime_lock);
162 clock_was_set();
163
164 return 0;
165}
166
167EXPORT_SYMBOL(do_settimeofday);
168
169
170
171
172
173
174
175
176
177
178
179static inline int set_rtc_mmss(unsigned long nowtime)
180{
181 return 0;
182}
183
184
185static long last_rtc_update = 0;
186
187
188
189
190
191irqreturn_t timer_interrupt(int irq, void *dev_id)
192{
193#ifndef CONFIG_SMP
194 profile_tick(CPU_PROFILING);
195#endif
196 do_timer(1);
197
198#ifndef CONFIG_SMP
199 update_process_times(user_mode(get_irq_regs()));
200#endif
201
202
203
204
205
206 write_seqlock(&xtime_lock);
207 if (ntp_synced()
208 && xtime.tv_sec > last_rtc_update + 660
209 && (xtime.tv_nsec / 1000) >= 500000 - ((unsigned)TICK_SIZE) / 2
210 && (xtime.tv_nsec / 1000) <= 500000 + ((unsigned)TICK_SIZE) / 2)
211 {
212 if (set_rtc_mmss(xtime.tv_sec) == 0)
213 last_rtc_update = xtime.tv_sec;
214 else
215 last_rtc_update = xtime.tv_sec - 600;
216 }
217 write_sequnlock(&xtime_lock);
218
219
220
221
222
223#ifdef CONFIG_SMP
224 smp_local_timer_interrupt();
225 smp_send_timer();
226#endif
227
228 return IRQ_HANDLED;
229}
230
231struct irqaction irq0 = {
232 .handler = timer_interrupt,
233 .flags = IRQF_DISABLED,
234 .mask = CPU_MASK_NONE,
235 .name = "MFT2",
236};
237
238void __init time_init(void)
239{
240 unsigned int epoch, year, mon, day, hour, min, sec;
241
242 sec = min = hour = day = mon = year = 0;
243 epoch = 0;
244
245 year = 23;
246 mon = 4;
247 day = 17;
248
249
250
251
252 if (year > 10 && year < 44)
253 epoch = 1980;
254 else if (year < 96)
255 epoch = 1952;
256 year += epoch;
257
258 xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
259 xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
260 set_normalized_timespec(&wall_to_monotonic,
261 -xtime.tv_sec, -xtime.tv_nsec);
262
263#if defined(CONFIG_CHIP_M32102) || defined(CONFIG_CHIP_XNUX2) \
264 || defined(CONFIG_CHIP_VDEC2) || defined(CONFIG_CHIP_M32700) \
265 || defined(CONFIG_CHIP_OPSP) || defined(CONFIG_CHIP_M32104)
266
267
268 setup_irq(M32R_IRQ_MFT2, &irq0);
269 {
270 unsigned long bus_clock;
271 unsigned short divide;
272
273 bus_clock = boot_cpu_data.bus_clock;
274 divide = boot_cpu_data.timer_divide;
275 latch = (bus_clock/divide + HZ / 2) / HZ;
276
277 printk("Timer start : latch = %ld\n", latch);
278
279 outl((M32R_MFTMOD_CC_MASK | M32R_MFTMOD_TCCR \
280 |M32R_MFTMOD_CSSEL011), M32R_MFT2MOD_PORTL);
281 outl(latch, M32R_MFT2RLD_PORTL);
282 outl(latch, M32R_MFT2CUT_PORTL);
283 outl(0, M32R_MFT2CMPRLD_PORTL);
284 outl((M32R_MFTCR_MFT2MSK|M32R_MFTCR_MFT2EN), M32R_MFTCR_PORTL);
285 }
286
287#elif defined(CONFIG_CHIP_M32310)
288#warning time_init not implemented
289#else
290#error no chip configuration
291#endif
292}
293