File: /usr/src/linux/arch/mips/mips-boards/generic/time.c
1 /*
2 * Carsten Langgaard, carstenl@mips.com
3 * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
4 *
5 * ########################################################################
6 *
7 * This program is free software; you can distribute it and/or modify it
8 * under the terms of the GNU General Public License (Version 2) as
9 * published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
19 *
20 * ########################################################################
21 *
22 * Setting up the clock on the MIPS boards.
23 *
24 */
25
26 #include <linux/config.h>
27 #include <linux/init.h>
28 #include <linux/kernel_stat.h>
29 #include <linux/sched.h>
30 #include <linux/spinlock.h>
31
32 #include <asm/mipsregs.h>
33 #include <asm/ptrace.h>
34 #include <asm/div64.h>
35
36 #include <linux/mc146818rtc.h>
37 #include <linux/timex.h>
38
39 #include <asm/mips-boards/generic.h>
40 #include <asm/mips-boards/prom.h>
41
42 extern volatile unsigned long wall_jiffies;
43 static long last_rtc_update = 0;
44 unsigned long missed_heart_beats = 0;
45
46 static unsigned long r4k_offset; /* Amount to increment compare reg each time */
47 static unsigned long r4k_cur; /* What counter should be at next timer irq */
48 extern rwlock_t xtime_lock;
49
50 #define ALLINTS (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5)
51
52 #if defined(CONFIG_MIPS_ATLAS)
53 static char display_string[] = " LINUX ON ATLAS ";
54 #endif
55 #if defined(CONFIG_MIPS_MALTA)
56 static char display_string[] = " LINUX ON MALTA ";
57 #endif
58 static unsigned int display_count = 0;
59 #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8)
60
61 static unsigned int timer_tick_count=0;
62
63
64 static inline void ack_r4ktimer(unsigned long newval)
65 {
66 write_32bit_cp0_register(CP0_COMPARE, newval);
67 }
68
69
70 /*
71 * In order to set the CMOS clock precisely, set_rtc_mmss has to be
72 * called 500 ms after the second nowtime has started, because when
73 * nowtime is written into the registers of the CMOS clock, it will
74 * jump to the next second precisely 500 ms later. Check the Motorola
75 * MC146818A or Dallas DS12887 data sheet for details.
76 *
77 * BUG: This routine does not handle hour overflow properly; it just
78 * sets the minutes. Usually you won't notice until after reboot!
79 */
80 static int set_rtc_mmss(unsigned long nowtime)
81 {
82 int retval = 0;
83 int real_seconds, real_minutes, cmos_minutes;
84 unsigned char save_control, save_freq_select;
85
86 save_control = CMOS_READ(RTC_CONTROL); /* tell the clock it's being set */
87 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
88
89 save_freq_select = CMOS_READ(RTC_FREQ_SELECT); /* stop and reset prescaler */
90 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
91
92 cmos_minutes = CMOS_READ(RTC_MINUTES);
93
94 /*
95 * since we're only adjusting minutes and seconds,
96 * don't interfere with hour overflow. This avoids
97 * messing with unknown time zones but requires your
98 * RTC not to be off by more than 15 minutes
99 */
100 real_seconds = nowtime % 60;
101 real_minutes = nowtime / 60;
102 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
103 real_minutes += 30; /* correct for half hour time zone */
104 real_minutes %= 60;
105
106 if (abs(real_minutes - cmos_minutes) < 30) {
107 CMOS_WRITE(real_seconds,RTC_SECONDS);
108 CMOS_WRITE(real_minutes,RTC_MINUTES);
109 } else {
110 printk(KERN_WARNING
111 "set_rtc_mmss: can't update from %d to %d\n",
112 cmos_minutes, real_minutes);
113 retval = -1;
114 }
115
116 /* The following flags have to be released exactly in this order,
117 * otherwise the DS12887 (popular MC146818A clone with integrated
118 * battery and quartz) will not reset the oscillator and will not
119 * update precisely 500 ms later. You won't find this mentioned in
120 * the Dallas Semiconductor data sheets, but who believes data
121 * sheets anyway ... -- Markus Kuhn
122 */
123 CMOS_WRITE(save_control, RTC_CONTROL);
124 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
125
126 return retval;
127 }
128
129 /*
130 * There are a lot of conceptually broken versions of the MIPS timer interrupt
131 * handler floating around. This one is rather different, but the algorithm
132 * is provably more robust.
133 */
134 void mips_timer_interrupt(struct pt_regs *regs)
135 {
136 int irq = 7;
137
138 if (r4k_offset == 0)
139 goto null;
140
141 do {
142 kstat.irqs[0][irq]++;
143 do_timer(regs);
144
145 /* Historical comment/code:
146 * RTC time of day s updated approx. every 11
147 * minutes. Because of how the numbers work out
148 * we need to make absolutely sure we do this update
149 * within 500ms before the * next second starts,
150 * thus the following code.
151 */
152 read_lock(&xtime_lock);
153 if ((time_status & STA_UNSYNC) == 0
154 && xtime.tv_sec > last_rtc_update + 660
155 && xtime.tv_usec >= 500000 - (tick >> 1)
156 && xtime.tv_usec <= 500000 + (tick >> 1))
157 if (set_rtc_mmss(xtime.tv_sec) == 0)
158 last_rtc_update = xtime.tv_sec;
159 else
160 /* do it again in 60 s */
161 last_rtc_update = xtime.tv_sec - 600;
162 read_unlock(&xtime_lock);
163
164 if ((timer_tick_count++ % HZ) == 0) {
165 mips_display_message(&display_string[display_count++]);
166 if (display_count == MAX_DISPLAY_COUNT)
167 display_count = 0;
168 }
169
170 r4k_cur += r4k_offset;
171 ack_r4ktimer(r4k_cur);
172
173 } while (((unsigned long)read_32bit_cp0_register(CP0_COUNT)
174 - r4k_cur) < 0x7fffffff);
175
176 return;
177
178 null:
179 ack_r4ktimer(0);
180 }
181
182 /*
183 * Figure out the r4k offset, the amount to increment the compare
184 * register for each time tick.
185 * Use the RTC to calculate offset.
186 */
187 static unsigned long __init cal_r4koff(void)
188 {
189 unsigned long count;
190 unsigned int flags;
191
192 __save_and_cli(flags);
193
194 /* Start counter exactly on falling edge of update flag */
195 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
196 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
197
198 /* Start r4k counter. */
199 write_32bit_cp0_register(CP0_COUNT, 0);
200
201 /* Read counter exactly on falling edge of update flag */
202 while (CMOS_READ(RTC_REG_A) & RTC_UIP);
203 while (!(CMOS_READ(RTC_REG_A) & RTC_UIP));
204
205 count = read_32bit_cp0_register(CP0_COUNT);
206
207 /* restore interrupts */
208 __restore_flags(flags);
209
210 return (count / HZ);
211 }
212
213 static unsigned long __init get_mips_time(void)
214 {
215 unsigned int year, mon, day, hour, min, sec;
216 unsigned char save_control;
217
218 save_control = CMOS_READ(RTC_CONTROL);
219
220 /* Freeze it. */
221 CMOS_WRITE(save_control | RTC_SET, RTC_CONTROL);
222
223 /* Read regs. */
224 sec = CMOS_READ(RTC_SECONDS);
225 min = CMOS_READ(RTC_MINUTES);
226 hour = CMOS_READ(RTC_HOURS);
227
228 if (!(save_control & RTC_24H))
229 {
230 if ((hour & 0xf) == 0xc)
231 hour &= 0x80;
232 if (hour & 0x80)
233 hour = (hour & 0xf) + 12;
234 }
235 day = CMOS_READ(RTC_DAY_OF_MONTH);
236 mon = CMOS_READ(RTC_MONTH);
237 year = CMOS_READ(RTC_YEAR);
238
239 /* Unfreeze clock. */
240 CMOS_WRITE(save_control, RTC_CONTROL);
241
242 if ((year += 1900) < 1970)
243 year += 100;
244
245 return mktime(year, mon, day, hour, min, sec);
246 }
247
248 void __init time_init(void)
249 {
250 unsigned int est_freq, flags;
251
252 /* Set Data mode - binary. */
253 CMOS_WRITE(CMOS_READ(RTC_CONTROL) | RTC_DM_BINARY, RTC_CONTROL);
254
255 printk("calculating r4koff... ");
256 r4k_offset = cal_r4koff();
257 printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
258
259 est_freq = 2*r4k_offset*HZ;
260 est_freq += 5000; /* round */
261 est_freq -= est_freq%10000;
262 printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
263 (est_freq%1000000)*100/1000000);
264 r4k_cur = (read_32bit_cp0_register(CP0_COUNT) + r4k_offset);
265
266 write_32bit_cp0_register(CP0_COMPARE, r4k_cur);
267 change_cp0_status(ST0_IM, ALLINTS);
268
269 /* Read time from the RTC chipset. */
270 write_lock_irqsave (&xtime_lock, flags);
271 xtime.tv_sec = get_mips_time();
272 xtime.tv_usec = 0;
273 write_unlock_irqrestore(&xtime_lock, flags);
274 }
275
276 /* This is for machines which generate the exact clock. */
277 #define USECS_PER_JIFFY (1000000/HZ)
278 #define USECS_PER_JIFFY_FRAC ((1000000 << 32) / HZ & 0xffffffff)
279
280 /* Cycle counter value at the previous timer interrupt.. */
281
282 static unsigned int timerhi = 0, timerlo = 0;
283
284 /*
285 * FIXME: Does playing with the RP bit in c0_status interfere with this code?
286 */
287 static unsigned long do_fast_gettimeoffset(void)
288 {
289 u32 count;
290 unsigned long res, tmp;
291
292 /* Last jiffy when do_fast_gettimeoffset() was called. */
293 static unsigned long last_jiffies=0;
294 unsigned long quotient;
295
296 /*
297 * Cached "1/(clocks per usec)*2^32" value.
298 * It has to be recalculated once each jiffy.
299 */
300 static unsigned long cached_quotient=0;
301
302 tmp = jiffies;
303
304 quotient = cached_quotient;
305
306 if (tmp && last_jiffies != tmp) {
307 last_jiffies = tmp;
308 #ifdef CONFIG_CPU_MIPS32
309 if (last_jiffies != 0) {
310 unsigned long r0;
311 do_div64_32(r0, timerhi, timerlo, tmp);
312 do_div64_32(quotient, USECS_PER_JIFFY,
313 USECS_PER_JIFFY_FRAC, r0);
314 cached_quotient = quotient;
315 }
316 #else
317 __asm__(".set\tnoreorder\n\t"
318 ".set\tnoat\n\t"
319 ".set\tmips3\n\t"
320 "lwu\t%0,%2\n\t"
321 "dsll32\t$1,%1,0\n\t"
322 "or\t$1,$1,%0\n\t"
323 "ddivu\t$0,$1,%3\n\t"
324 "mflo\t$1\n\t"
325 "dsll32\t%0,%4,0\n\t"
326 "nop\n\t"
327 "ddivu\t$0,%0,$1\n\t"
328 "mflo\t%0\n\t"
329 ".set\tmips0\n\t"
330 ".set\tat\n\t"
331 ".set\treorder"
332 :"=&r" (quotient)
333 :"r" (timerhi),
334 "m" (timerlo),
335 "r" (tmp),
336 "r" (USECS_PER_JIFFY)
337 :"$1");
338 cached_quotient = quotient;
339 #endif
340 }
341
342 /* Get last timer tick in absolute kernel time */
343 count = read_32bit_cp0_register(CP0_COUNT);
344
345 /* .. relative to previous jiffy (32 bits is enough) */
346 count -= timerlo;
347
348 __asm__("multu\t%1,%2\n\t"
349 "mfhi\t%0"
350 :"=r" (res)
351 :"r" (count),
352 "r" (quotient));
353
354 /*
355 * Due to possible jiffies inconsistencies, we need to check
356 * the result so that we'll get a timer that is monotonic.
357 */
358 if (res >= USECS_PER_JIFFY)
359 res = USECS_PER_JIFFY-1;
360
361 return res;
362 }
363
364 void do_gettimeofday(struct timeval *tv)
365 {
366 unsigned int flags;
367
368 read_lock_irqsave (&xtime_lock, flags);
369 *tv = xtime;
370 tv->tv_usec += do_fast_gettimeoffset();
371
372 /*
373 * xtime is atomically updated in timer_bh. jiffies - wall_jiffies
374 * is nonzero if the timer bottom half hasnt executed yet.
375 */
376 if (jiffies - wall_jiffies)
377 tv->tv_usec += USECS_PER_JIFFY;
378
379 read_unlock_irqrestore (&xtime_lock, flags);
380
381 if (tv->tv_usec >= 1000000) {
382 tv->tv_usec -= 1000000;
383 tv->tv_sec++;
384 }
385 }
386
387 void do_settimeofday(struct timeval *tv)
388 {
389 write_lock_irq (&xtime_lock);
390
391 /* This is revolting. We need to set the xtime.tv_usec correctly.
392 * However, the value in this location is is value at the last tick.
393 * Discover what correction gettimeofday would have done, and then
394 * undo it!
395 */
396 tv->tv_usec -= do_fast_gettimeoffset();
397
398 if (tv->tv_usec < 0) {
399 tv->tv_usec += 1000000;
400 tv->tv_sec--;
401 }
402
403 xtime = *tv;
404 time_adjust = 0; /* stop active adjtime() */
405 time_status |= STA_UNSYNC;
406 time_maxerror = NTP_PHASE_LIMIT;
407 time_esterror = NTP_PHASE_LIMIT;
408
409 write_unlock_irq (&xtime_lock);
410 }
411