1 /* $Id: time.c,v 1.22 1999/08/30 10:01:22 davem Exp $
2 * time.c: UltraSparc timer and TOD clock support.
4 * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
5 * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
7 * Based largely on code which is:
9 * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
12 #include <linux/config.h>
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/param.h>
17 #include <linux/string.h>
19 #include <linux/interrupt.h>
20 #include <linux/timex.h>
21 #include <linux/init.h>
22 #include <linux/ioport.h>
24 #include <asm/oplib.h>
25 #include <asm/mostek.h>
26 #include <asm/timer.h>
34 extern rwlock_t xtime_lock
;
36 unsigned long mstk48t02_regs
= 0UL;
37 static unsigned long mstk48t08_regs
= 0UL;
38 static unsigned long mstk48t59_regs
= 0UL;
40 static int set_rtc_mmss(unsigned long);
42 /* timer_interrupt() needs to keep up the real-time clock,
43 * as well as call the "do_timer()" routine every clocktick
45 * NOTE: On SUN5 systems the ticker interrupt comes in using 2
46 * interrupts, one at level14 and one with softint bit 0.
48 unsigned long timer_tick_offset
;
49 static unsigned long timer_tick_compare
;
50 static unsigned long timer_ticks_per_usec_quotient
;
52 static __inline__
void timer_check_rtc(void)
54 /* last time the cmos clock got updated */
55 static long last_rtc_update
=0;
57 /* Determine when to update the Mostek clock. */
58 if ((time_status
& STA_UNSYNC
) == 0 &&
59 xtime
.tv_sec
> last_rtc_update
+ 660 &&
60 xtime
.tv_usec
>= 500000 - ((unsigned) tick
) / 2 &&
61 xtime
.tv_usec
<= 500000 + ((unsigned) tick
) / 2) {
62 if (set_rtc_mmss(xtime
.tv_sec
) == 0)
63 last_rtc_update
= xtime
.tv_sec
;
65 last_rtc_update
= xtime
.tv_sec
- 600;
66 /* do it again in 60 s */
70 static void timer_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
)
74 write_lock(&xtime_lock
);
79 __asm__
__volatile__("
84 : "=&r" (timer_tick_compare
), "=r" (ticks
)
85 : "r" (timer_tick_offset
));
86 } while (ticks
>= timer_tick_compare
);
90 write_unlock(&xtime_lock
);
94 void timer_tick_interrupt(struct pt_regs
*regs
)
96 write_lock(&xtime_lock
);
101 * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR.
103 __asm__
__volatile__("
106 : "=&r" (timer_tick_compare
)
107 : "r" (timer_tick_offset
));
111 write_unlock(&xtime_lock
);
115 /* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
116 * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
117 * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
119 * [For the Julian calendar (which was used in Russia before 1917,
120 * Britain & colonies before 1752, anywhere else before 1582,
121 * and is still in use by some communities) leave out the
122 * -year/100+year/400 terms, and add 10.]
124 * This algorithm was first published by Gauss (I think).
126 * WARNING: this function will overflow on 2106-02-07 06:28:16 on
127 * machines were long is 32-bit! (However, as time_t is signed, we
128 * will already get problems at other places on 2038-01-19 03:14:08)
130 static inline unsigned long mktime(unsigned int year
, unsigned int mon
,
131 unsigned int day
, unsigned int hour
,
132 unsigned int min
, unsigned int sec
)
134 if (0 >= (int) (mon
-= 2)) { /* 1..12 -> 11,12,1..10 */
135 mon
+= 12; /* Puts Feb last since it has leap day */
139 (unsigned long)(year
/4 - year
/100 + year
/400 + 367*mon
/12 + day
) +
141 )*24 + hour
/* now have hours */
142 )*60 + min
/* now have minutes */
143 )*60 + sec
; /* finally seconds */
146 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
147 static void __init
kick_start_clock(void)
149 unsigned long regs
= mstk48t02_regs
;
153 prom_printf("CLOCK: Clock was stopped. Kick start ");
155 /* Turn on the kick start bit to start the oscillator. */
156 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
157 tmp
|= MSTK_CREG_WRITE
;
158 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
159 tmp
= mostek_read(regs
+ MOSTEK_SEC
);
161 mostek_write(regs
+ MOSTEK_SEC
, tmp
);
162 tmp
= mostek_read(regs
+ MOSTEK_HOUR
);
163 tmp
|= MSTK_KICK_START
;
164 mostek_write(regs
+ MOSTEK_HOUR
, tmp
);
165 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
166 tmp
&= ~MSTK_CREG_WRITE
;
167 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
169 /* Delay to allow the clock oscillator to start. */
170 sec
= MSTK_REG_SEC(regs
);
171 for (i
= 0; i
< 3; i
++) {
172 while (sec
== MSTK_REG_SEC(regs
))
173 for (count
= 0; count
< 100000; count
++)
176 sec
= MSTK_REG_SEC(regs
);
180 /* Turn off kick start and set a "valid" time and date. */
181 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
182 tmp
|= MSTK_CREG_WRITE
;
183 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
184 tmp
= mostek_read(regs
+ MOSTEK_HOUR
);
185 tmp
&= ~MSTK_KICK_START
;
186 mostek_write(regs
+ MOSTEK_HOUR
, tmp
);
187 MSTK_SET_REG_SEC(regs
,0);
188 MSTK_SET_REG_MIN(regs
,0);
189 MSTK_SET_REG_HOUR(regs
,0);
190 MSTK_SET_REG_DOW(regs
,5);
191 MSTK_SET_REG_DOM(regs
,1);
192 MSTK_SET_REG_MONTH(regs
,8);
193 MSTK_SET_REG_YEAR(regs
,1996 - MSTK_YEAR_ZERO
);
194 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
195 tmp
&= ~MSTK_CREG_WRITE
;
196 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
198 /* Ensure the kick start bit is off. If it isn't, turn it off. */
199 while (mostek_read(regs
+ MOSTEK_HOUR
) & MSTK_KICK_START
) {
200 prom_printf("CLOCK: Kick start still on!\n");
201 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
202 tmp
|= MSTK_CREG_WRITE
;
203 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
205 tmp
= mostek_read(regs
+ MOSTEK_HOUR
);
206 tmp
&= ~MSTK_KICK_START
;
207 mostek_write(regs
+ MOSTEK_HOUR
, tmp
);
209 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
210 tmp
&= ~MSTK_CREG_WRITE
;
211 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
214 prom_printf("CLOCK: Kick start procedure successful.\n");
217 /* Return nonzero if the clock chip battery is low. */
218 static int __init
has_low_battery(void)
220 unsigned long regs
= mstk48t02_regs
;
223 data1
= mostek_read(regs
+ MOSTEK_EEPROM
); /* Read some data. */
224 mostek_write(regs
+ MOSTEK_EEPROM
, ~data1
); /* Write back the complement. */
225 data2
= mostek_read(regs
+ MOSTEK_EEPROM
); /* Read back the complement. */
226 mostek_write(regs
+ MOSTEK_EEPROM
, data1
); /* Restore original value. */
228 return (data1
== data2
); /* Was the write blocked? */
232 /* Probe for the real time clock chip. */
233 static void __init
set_system_time(void)
235 unsigned int year
, mon
, day
, hour
, min
, sec
;
236 unsigned long mregs
= mstk48t02_regs
;
239 do_get_fast_time
= do_gettimeofday
;
242 prom_printf("Something wrong, clock regs not mapped yet.\n");
246 tmp
= mostek_read(mregs
+ MOSTEK_CREG
);
247 tmp
|= MSTK_CREG_READ
;
248 mostek_write(mregs
+ MOSTEK_CREG
, tmp
);
250 sec
= MSTK_REG_SEC(mregs
);
251 min
= MSTK_REG_MIN(mregs
);
252 hour
= MSTK_REG_HOUR(mregs
);
253 day
= MSTK_REG_DOM(mregs
);
254 mon
= MSTK_REG_MONTH(mregs
);
255 year
= MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs
) );
256 xtime
.tv_sec
= mktime(year
, mon
, day
, hour
, min
, sec
);
259 tmp
= mostek_read(mregs
+ MOSTEK_CREG
);
260 tmp
&= ~MSTK_CREG_READ
;
261 mostek_write(mregs
+ MOSTEK_CREG
, tmp
);
264 void __init
clock_probe(void)
266 struct linux_prom_registers clk_reg
[2];
268 int node
, busnd
= -1, err
;
271 struct linux_ebus
*ebus
= 0;
274 __save_and_cli(flags
);
276 if(central_bus
!= NULL
) {
277 busnd
= central_bus
->child
->prom_node
;
280 else if (ebus_chain
!= NULL
) {
282 busnd
= ebus
->prom_node
;
286 busnd
= SBus_chain
->prom_node
;
290 prom_printf("clock_probe: problem, cannot find bus to search.\n");
294 node
= prom_getchild(busnd
);
300 prom_getstring(node
, "model", model
, sizeof(model
));
301 if(strcmp(model
, "mk48t02") &&
302 strcmp(model
, "mk48t08") &&
303 strcmp(model
, "mk48t59")) {
305 node
= prom_getsibling(node
);
307 while ((node
== 0) && ebus
) {
310 busnd
= ebus
->prom_node
;
311 node
= prom_getchild(busnd
);
316 prom_printf("clock_probe: Cannot find timer chip\n");
322 err
= prom_getproperty(node
, "reg", (char *)clk_reg
,
325 prom_printf("clock_probe: Cannot get Mostek reg property\n");
330 prom_apply_fhc_ranges(central_bus
->child
, clk_reg
, 1);
331 prom_apply_central_ranges(central_bus
, clk_reg
, 1);
334 else if (ebus_chain
) {
335 struct linux_ebus_device
*edev
;
337 for_each_ebusdev(edev
, ebus
)
338 if (edev
->prom_node
== node
)
341 prom_printf("%s: Mostek not probed by EBUS\n",
346 mstk48t59_regs
= edev
->resource
[0].start
;
347 mstk48t02_regs
= mstk48t59_regs
+ MOSTEK_48T59_48T02
;
352 prom_adjust_regs(clk_reg
, 1,
353 SBus_chain
->sbus_ranges
,
354 SBus_chain
->num_sbus_ranges
);
357 if(model
[5] == '0' && model
[6] == '2') {
358 mstk48t02_regs
= (((u64
)clk_reg
[0].phys_addr
) |
359 (((u64
)clk_reg
[0].which_io
)<<32UL));
360 } else if(model
[5] == '0' && model
[6] == '8') {
361 mstk48t08_regs
= (((u64
)clk_reg
[0].phys_addr
) |
362 (((u64
)clk_reg
[0].which_io
)<<32UL));
363 mstk48t02_regs
= mstk48t08_regs
+ MOSTEK_48T08_48T02
;
365 mstk48t59_regs
= (((u64
)clk_reg
[0].phys_addr
) |
366 (((u64
)clk_reg
[0].which_io
)<<32UL));
367 mstk48t02_regs
= mstk48t59_regs
+ MOSTEK_48T59_48T02
;
372 /* Report a low battery voltage condition. */
373 if (has_low_battery())
374 prom_printf("NVRAM: Low battery voltage!\n");
376 /* Kick start the clock if it is completely stopped. */
377 if (mostek_read(mstk48t02_regs
+ MOSTEK_SEC
) & MSTK_STOP
)
382 __restore_flags(flags
);
386 #define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
390 #define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
393 extern void init_timers(void (*func
)(int, void *, struct pt_regs
*),
396 void __init
time_init(void)
398 /* clock_probe() is now done at end of [se]bus_init on sparc64
399 * so that sbus, fhc and ebus bus information is probed and
404 init_timers(timer_interrupt
, &clock
);
405 timer_tick_offset
= clock
/ HZ
;
406 timer_ticks_per_usec_quotient
= ((1UL<<32) / (clock
/ 1000020));
409 static __inline__
unsigned long do_gettimeoffset(void)
413 __asm__
__volatile__("
419 : "r" (timer_tick_offset
), "r" (timer_tick_compare
)
422 return (ticks
* timer_ticks_per_usec_quotient
) >> 32UL;
425 /* This need not obtain the xtime_lock as it is coded in
426 * an implicitly SMP safe way already.
428 void do_gettimeofday(struct timeval
*tv
)
430 /* Load doubles must be used on xtime so that what we get
431 * is guarenteed to be atomic, this is why we can run this
432 * with interrupts on full blast. Don't touch this... -DaveM
434 * Note with time_t changes to the timeval type, I must now use
435 * nucleus atomic quad 128-bit loads.
437 __asm__
__volatile__("
438 sethi %hi(timer_tick_offset), %g3
439 sethi %hi(xtime), %g2
440 sethi %hi(timer_tick_compare), %g1
441 ldx [%g3 + %lo(timer_tick_offset)], %g3
442 or %g2, %lo(xtime), %g2
443 or %g1, %lo(timer_tick_compare), %g1
444 1: ldda [%g2] 0x24, %o4
452 sethi %hi(lost_ticks), %o2
453 sethi %hi(timer_ticks_per_usec_quotient), %o3
454 ldx [%o2 + %lo(lost_ticks)], %o2
456 ldx [%o3 + %lo(timer_ticks_per_usec_quotient)], %o3
461 sethi %hi(10000), %g2
462 or %g2, %lo(10000), %g2
464 1: sethi %hi(1000000), %o2
466 or %o2, %lo(1000000), %o2
474 1: st %o5, [%o0 + 0x8]");
477 void do_settimeofday(struct timeval
*tv
)
479 write_lock_irq(&xtime_lock
);
481 tv
->tv_usec
-= do_gettimeoffset();
482 if(tv
->tv_usec
< 0) {
483 tv
->tv_usec
+= 1000000;
488 time_adjust
= 0; /* stop active adjtime() */
489 time_status
|= STA_UNSYNC
;
490 time_maxerror
= NTP_PHASE_LIMIT
;
491 time_esterror
= NTP_PHASE_LIMIT
;
493 write_unlock_irq(&xtime_lock
);
496 static int set_rtc_mmss(unsigned long nowtime
)
498 int real_seconds
, real_minutes
, mostek_minutes
;
499 unsigned long regs
= mstk48t02_regs
;
502 /* Not having a register set can lead to trouble. */
506 /* Read the current RTC minutes. */
507 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
508 tmp
|= MSTK_CREG_READ
;
509 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
511 mostek_minutes
= MSTK_REG_MIN(regs
);
513 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
514 tmp
&= ~MSTK_CREG_READ
;
515 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
518 * since we're only adjusting minutes and seconds,
519 * don't interfere with hour overflow. This avoids
520 * messing with unknown time zones but requires your
521 * RTC not to be off by more than 15 minutes
523 real_seconds
= nowtime
% 60;
524 real_minutes
= nowtime
/ 60;
525 if (((abs(real_minutes
- mostek_minutes
) + 15)/30) & 1)
526 real_minutes
+= 30; /* correct for half hour time zone */
529 if (abs(real_minutes
- mostek_minutes
) < 30) {
530 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
531 tmp
|= MSTK_CREG_WRITE
;
532 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
534 MSTK_SET_REG_SEC(regs
,real_seconds
);
535 MSTK_SET_REG_MIN(regs
,real_minutes
);
537 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
538 tmp
&= ~MSTK_CREG_WRITE
;
539 mostek_write(regs
+ MOSTEK_CREG
, tmp
);