1 /* $Id: time.c,v 1.32 2000/09/22 23:02:13 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>
33 #include <asm/starfire.h>
35 extern rwlock_t xtime_lock
;
37 unsigned long mstk48t02_regs
= 0UL;
38 static unsigned long mstk48t08_regs
= 0UL;
39 static unsigned long mstk48t59_regs
= 0UL;
41 static int set_rtc_mmss(unsigned long);
43 /* timer_interrupt() needs to keep up the real-time clock,
44 * as well as call the "do_timer()" routine every clocktick
46 * NOTE: On SUN5 systems the ticker interrupt comes in using 2
47 * interrupts, one at level14 and one with softint bit 0.
49 unsigned long timer_tick_offset
;
50 unsigned long timer_tick_compare
;
51 unsigned long timer_ticks_per_usec_quotient
;
53 static __inline__
void timer_check_rtc(void)
55 /* last time the cmos clock got updated */
56 static long last_rtc_update
=0;
58 /* Determine when to update the Mostek clock. */
59 if ((time_status
& STA_UNSYNC
) == 0 &&
60 xtime
.tv_sec
> last_rtc_update
+ 660 &&
61 xtime
.tv_usec
>= 500000 - ((unsigned) tick
) / 2 &&
62 xtime
.tv_usec
<= 500000 + ((unsigned) tick
) / 2) {
63 if (set_rtc_mmss(xtime
.tv_sec
) == 0)
64 last_rtc_update
= xtime
.tv_sec
;
66 last_rtc_update
= xtime
.tv_sec
- 600;
67 /* do it again in 60 s */
71 void sparc64_do_profile(unsigned long pc
, unsigned long o7
)
73 if (prof_buffer
&& current
->pid
) {
75 extern int rwlock_impl_begin
, rwlock_impl_end
;
76 extern int atomic_impl_begin
, atomic_impl_end
;
77 extern int __memcpy_begin
, __memcpy_end
;
78 extern int __bitops_begin
, __bitops_end
;
80 if ((pc
>= (unsigned long) &atomic_impl_begin
&&
81 pc
< (unsigned long) &atomic_impl_end
) ||
82 (pc
>= (unsigned long) &rwlock_impl_begin
&&
83 pc
< (unsigned long) &rwlock_impl_end
) ||
84 (pc
>= (unsigned long) &__memcpy_begin
&&
85 pc
< (unsigned long) &__memcpy_end
) ||
86 (pc
>= (unsigned long) &__bitops_begin
&&
87 pc
< (unsigned long) &__bitops_end
))
90 pc
-= (unsigned long) &_stext
;
95 atomic_inc((atomic_t
*)&prof_buffer
[pc
]);
99 static void timer_interrupt(int irq
, void *dev_id
, struct pt_regs
* regs
)
101 unsigned long ticks
, pstate
;
103 write_lock(&xtime_lock
);
107 if ((regs
->tstate
& TSTATE_PRIV
) != 0)
108 sparc64_do_profile(regs
->tpc
, regs
->u_regs
[UREG_RETPC
]);
112 /* Guarentee that the following sequences execute
115 __asm__
__volatile__("rdpr %%pstate, %0\n\t"
116 "wrpr %0, %1, %%pstate"
120 /* Workaround for Spitfire Errata (#54 I think??), I discovered
121 * this via Sun BugID 4008234, mentioned in Solaris-2.5.1 patch
124 * On Blackbird writes to %tick_cmpr can fail, the
125 * workaround seems to be to execute the wr instruction
126 * at the start of an I-cache line, and perform a dummy
127 * read back from %tick_cmpr right after writing to it. -DaveM
129 * Just to be anal we add a workaround for Spitfire
130 * Errata 50 by preventing pipeline bypasses on the
131 * final read of the %tick register into a compare
132 * instruction. The Errata 50 description states
133 * that %tick is not prone to this bug, but I am not
134 * taking any chances.
136 __asm__
__volatile__("
141 1: wr %0, 0, %%tick_cmpr
145 : "=&r" (timer_tick_compare
), "=r" (ticks
)
146 : "r" (timer_tick_offset
));
148 /* Restore PSTATE_IE. */
149 __asm__
__volatile__("wrpr %0, 0x0, %%pstate"
152 } while (ticks
>= timer_tick_compare
);
156 write_unlock(&xtime_lock
);
160 void timer_tick_interrupt(struct pt_regs
*regs
)
162 write_lock(&xtime_lock
);
167 * Only keep timer_tick_offset uptodate, but don't set TICK_CMPR.
169 __asm__
__volatile__("
172 : "=&r" (timer_tick_compare
)
173 : "r" (timer_tick_offset
));
177 write_unlock(&xtime_lock
);
181 /* Kick start a stopped clock (procedure from the Sun NVRAM/hostid FAQ). */
182 static void __init
kick_start_clock(void)
184 unsigned long regs
= mstk48t02_regs
;
188 prom_printf("CLOCK: Clock was stopped. Kick start ");
190 /* Turn on the kick start bit to start the oscillator. */
191 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
192 tmp
|= MSTK_CREG_WRITE
;
193 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
194 tmp
= mostek_read(regs
+ MOSTEK_SEC
);
196 mostek_write(regs
+ MOSTEK_SEC
, tmp
);
197 tmp
= mostek_read(regs
+ MOSTEK_HOUR
);
198 tmp
|= MSTK_KICK_START
;
199 mostek_write(regs
+ MOSTEK_HOUR
, tmp
);
200 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
201 tmp
&= ~MSTK_CREG_WRITE
;
202 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
204 /* Delay to allow the clock oscillator to start. */
205 sec
= MSTK_REG_SEC(regs
);
206 for (i
= 0; i
< 3; i
++) {
207 while (sec
== MSTK_REG_SEC(regs
))
208 for (count
= 0; count
< 100000; count
++)
211 sec
= MSTK_REG_SEC(regs
);
215 /* Turn off kick start and set a "valid" time and date. */
216 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
217 tmp
|= MSTK_CREG_WRITE
;
218 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
219 tmp
= mostek_read(regs
+ MOSTEK_HOUR
);
220 tmp
&= ~MSTK_KICK_START
;
221 mostek_write(regs
+ MOSTEK_HOUR
, tmp
);
222 MSTK_SET_REG_SEC(regs
,0);
223 MSTK_SET_REG_MIN(regs
,0);
224 MSTK_SET_REG_HOUR(regs
,0);
225 MSTK_SET_REG_DOW(regs
,5);
226 MSTK_SET_REG_DOM(regs
,1);
227 MSTK_SET_REG_MONTH(regs
,8);
228 MSTK_SET_REG_YEAR(regs
,1996 - MSTK_YEAR_ZERO
);
229 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
230 tmp
&= ~MSTK_CREG_WRITE
;
231 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
233 /* Ensure the kick start bit is off. If it isn't, turn it off. */
234 while (mostek_read(regs
+ MOSTEK_HOUR
) & MSTK_KICK_START
) {
235 prom_printf("CLOCK: Kick start still on!\n");
236 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
237 tmp
|= MSTK_CREG_WRITE
;
238 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
240 tmp
= mostek_read(regs
+ MOSTEK_HOUR
);
241 tmp
&= ~MSTK_KICK_START
;
242 mostek_write(regs
+ MOSTEK_HOUR
, tmp
);
244 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
245 tmp
&= ~MSTK_CREG_WRITE
;
246 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
249 prom_printf("CLOCK: Kick start procedure successful.\n");
252 /* Return nonzero if the clock chip battery is low. */
253 static int __init
has_low_battery(void)
255 unsigned long regs
= mstk48t02_regs
;
258 data1
= mostek_read(regs
+ MOSTEK_EEPROM
); /* Read some data. */
259 mostek_write(regs
+ MOSTEK_EEPROM
, ~data1
); /* Write back the complement. */
260 data2
= mostek_read(regs
+ MOSTEK_EEPROM
); /* Read back the complement. */
261 mostek_write(regs
+ MOSTEK_EEPROM
, data1
); /* Restore original value. */
263 return (data1
== data2
); /* Was the write blocked? */
267 /* Probe for the real time clock chip. */
268 static void __init
set_system_time(void)
270 unsigned int year
, mon
, day
, hour
, min
, sec
;
271 unsigned long mregs
= mstk48t02_regs
;
274 do_get_fast_time
= do_gettimeofday
;
277 prom_printf("Something wrong, clock regs not mapped yet.\n");
281 tmp
= mostek_read(mregs
+ MOSTEK_CREG
);
282 tmp
|= MSTK_CREG_READ
;
283 mostek_write(mregs
+ MOSTEK_CREG
, tmp
);
285 sec
= MSTK_REG_SEC(mregs
);
286 min
= MSTK_REG_MIN(mregs
);
287 hour
= MSTK_REG_HOUR(mregs
);
288 day
= MSTK_REG_DOM(mregs
);
289 mon
= MSTK_REG_MONTH(mregs
);
290 year
= MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs
) );
291 xtime
.tv_sec
= mktime(year
, mon
, day
, hour
, min
, sec
);
294 tmp
= mostek_read(mregs
+ MOSTEK_CREG
);
295 tmp
&= ~MSTK_CREG_READ
;
296 mostek_write(mregs
+ MOSTEK_CREG
, tmp
);
299 void __init
clock_probe(void)
301 struct linux_prom_registers clk_reg
[2];
303 int node
, busnd
= -1, err
;
306 struct linux_ebus
*ebus
= NULL
;
310 if (this_is_starfire
) {
311 /* davem suggests we keep this within the 4M locked kernel image */
312 static char obp_gettod
[256];
315 sprintf(obp_gettod
, "h# %08x unix-gettod",
316 (unsigned int) (long) &unix_tod
);
317 prom_feval(obp_gettod
);
318 xtime
.tv_sec
= unix_tod
;
323 __save_and_cli(flags
);
325 if(central_bus
!= NULL
) {
326 busnd
= central_bus
->child
->prom_node
;
329 else if (ebus_chain
!= NULL
) {
331 busnd
= ebus
->prom_node
;
334 else if (sbus_root
!= NULL
) {
335 busnd
= sbus_root
->prom_node
;
339 prom_printf("clock_probe: problem, cannot find bus to search.\n");
343 node
= prom_getchild(busnd
);
349 prom_getstring(node
, "model", model
, sizeof(model
));
350 if(strcmp(model
, "mk48t02") &&
351 strcmp(model
, "mk48t08") &&
352 strcmp(model
, "mk48t59")) {
354 node
= prom_getsibling(node
);
356 while ((node
== 0) && ebus
!= NULL
) {
359 busnd
= ebus
->prom_node
;
360 node
= prom_getchild(busnd
);
365 prom_printf("clock_probe: Cannot find timer chip\n");
371 err
= prom_getproperty(node
, "reg", (char *)clk_reg
,
374 prom_printf("clock_probe: Cannot get Mostek reg property\n");
379 apply_fhc_ranges(central_bus
->child
, clk_reg
, 1);
380 apply_central_ranges(central_bus
, clk_reg
, 1);
383 else if (ebus_chain
!= NULL
) {
384 struct linux_ebus_device
*edev
;
386 for_each_ebusdev(edev
, ebus
)
387 if (edev
->prom_node
== node
)
390 prom_printf("%s: Mostek not probed by EBUS\n",
395 mstk48t59_regs
= edev
->resource
[0].start
;
396 mstk48t02_regs
= mstk48t59_regs
+ MOSTEK_48T59_48T02
;
401 if (sbus_root
->num_sbus_ranges
) {
402 int nranges
= sbus_root
->num_sbus_ranges
;
405 for (rngc
= 0; rngc
< nranges
; rngc
++)
406 if (clk_reg
[0].which_io
==
407 sbus_root
->sbus_ranges
[rngc
].ot_child_space
)
409 if (rngc
== nranges
) {
410 prom_printf("clock_probe: Cannot find ranges for "
414 clk_reg
[0].which_io
=
415 sbus_root
->sbus_ranges
[rngc
].ot_parent_space
;
416 clk_reg
[0].phys_addr
+=
417 sbus_root
->sbus_ranges
[rngc
].ot_parent_base
;
421 if(model
[5] == '0' && model
[6] == '2') {
422 mstk48t02_regs
= (((u64
)clk_reg
[0].phys_addr
) |
423 (((u64
)clk_reg
[0].which_io
)<<32UL));
424 } else if(model
[5] == '0' && model
[6] == '8') {
425 mstk48t08_regs
= (((u64
)clk_reg
[0].phys_addr
) |
426 (((u64
)clk_reg
[0].which_io
)<<32UL));
427 mstk48t02_regs
= mstk48t08_regs
+ MOSTEK_48T08_48T02
;
429 mstk48t59_regs
= (((u64
)clk_reg
[0].phys_addr
) |
430 (((u64
)clk_reg
[0].which_io
)<<32UL));
431 mstk48t02_regs
= mstk48t59_regs
+ MOSTEK_48T59_48T02
;
436 /* Report a low battery voltage condition. */
437 if (has_low_battery())
438 prom_printf("NVRAM: Low battery voltage!\n");
440 /* Kick start the clock if it is completely stopped. */
441 if (mostek_read(mstk48t02_regs
+ MOSTEK_SEC
) & MSTK_STOP
)
446 __restore_flags(flags
);
450 #define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
454 #define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
457 extern void init_timers(void (*func
)(int, void *, struct pt_regs
*),
460 void __init
time_init(void)
462 /* clock_probe() is now done at end of [se]bus_init on sparc64
463 * so that sbus, fhc and ebus bus information is probed and
468 init_timers(timer_interrupt
, &clock
);
469 timer_tick_offset
= clock
/ HZ
;
470 timer_ticks_per_usec_quotient
= ((1UL<<32) / (clock
/ 1000020));
473 static __inline__
unsigned long do_gettimeoffset(void)
477 __asm__
__volatile__("
483 : "r" (timer_tick_offset
), "r" (timer_tick_compare
)
486 return (ticks
* timer_ticks_per_usec_quotient
) >> 32UL;
489 void do_settimeofday(struct timeval
*tv
)
491 if (this_is_starfire
)
494 write_lock_irq(&xtime_lock
);
496 tv
->tv_usec
-= do_gettimeoffset();
497 if(tv
->tv_usec
< 0) {
498 tv
->tv_usec
+= 1000000;
503 time_adjust
= 0; /* stop active adjtime() */
504 time_status
|= STA_UNSYNC
;
505 time_maxerror
= NTP_PHASE_LIMIT
;
506 time_esterror
= NTP_PHASE_LIMIT
;
508 write_unlock_irq(&xtime_lock
);
511 static int set_rtc_mmss(unsigned long nowtime
)
513 int real_seconds
, real_minutes
, mostek_minutes
;
514 unsigned long regs
= mstk48t02_regs
;
518 * Not having a register set can lead to trouble.
519 * Also starfire doesnt have a tod clock.
524 /* Read the current RTC minutes. */
525 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
526 tmp
|= MSTK_CREG_READ
;
527 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
529 mostek_minutes
= MSTK_REG_MIN(regs
);
531 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
532 tmp
&= ~MSTK_CREG_READ
;
533 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
536 * since we're only adjusting minutes and seconds,
537 * don't interfere with hour overflow. This avoids
538 * messing with unknown time zones but requires your
539 * RTC not to be off by more than 15 minutes
541 real_seconds
= nowtime
% 60;
542 real_minutes
= nowtime
/ 60;
543 if (((abs(real_minutes
- mostek_minutes
) + 15)/30) & 1)
544 real_minutes
+= 30; /* correct for half hour time zone */
547 if (abs(real_minutes
- mostek_minutes
) < 30) {
548 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
549 tmp
|= MSTK_CREG_WRITE
;
550 mostek_write(regs
+ MOSTEK_CREG
, tmp
);
552 MSTK_SET_REG_SEC(regs
,real_seconds
);
553 MSTK_SET_REG_MIN(regs
,real_minutes
);
555 tmp
= mostek_read(regs
+ MOSTEK_CREG
);
556 tmp
&= ~MSTK_CREG_WRITE
;
557 mostek_write(regs
+ MOSTEK_CREG
, tmp
);