- Linus: more PageDirty / swapcache handling
[davej-history.git] / arch / mips64 / sgi-ip27 / ip27-timer.c
blobedbeb9e11ea5e5b142a8cc99d53c32c838d1440f
1 /*
2 * Copytight (C) 1999, 2000 Ralf Baechle (ralf@gnu.org)
3 * Copytight (C) 1999, 2000 Silicon Graphics, Inc.
4 */
5 #include <linux/config.h>
6 #include <linux/init.h>
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9 #include <linux/interrupt.h>
10 #include <linux/kernel_stat.h>
11 #include <linux/param.h>
12 #include <linux/timex.h>
13 #include <linux/mm.h>
15 #include <asm/pgtable.h>
16 #include <asm/sgialib.h>
17 #include <asm/sn/ioc3.h>
18 #include <asm/m48t35.h>
19 #include <asm/sn/klconfig.h>
20 #include <asm/sn/arch.h>
21 #include <asm/sn/addrs.h>
22 #include <asm/sn/sn_private.h>
23 #include <asm/sn/sn0/ip27.h>
24 #include <asm/sn/sn0/hub.h>
27 * This is a hack; we really need to figure these values out dynamically
29 * Since 800 ns works very well with various HUB frequencies, such as
30 * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
32 * Ralf: which clock rate is used to feed the counter?
34 #define NSEC_PER_CYCLE 800
35 #define NSEC_PER_SEC 1000000000
36 #define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
37 #define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ)
39 static unsigned long ct_cur[NR_CPUS]; /* What counter should be at next timer irq */
40 static long last_rtc_update; /* Last time the rtc clock got updated */
42 extern rwlock_t xtime_lock;
43 extern volatile unsigned long wall_jiffies;
46 static int set_rtc_mmss(unsigned long nowtime)
48 int retval = 0;
49 int real_seconds, real_minutes, cmos_minutes;
50 struct m48t35_rtc *rtc;
51 nasid_t nid;
53 nid = get_nasid();
54 rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
55 IOC3_BYTEBUS_DEV0);
57 rtc->control |= M48T35_RTC_READ;
58 cmos_minutes = rtc->min;
59 BCD_TO_BIN(cmos_minutes);
60 rtc->control &= ~M48T35_RTC_READ;
63 * Since we're only adjusting minutes and seconds, don't interfere with
64 * hour overflow. This avoids messing with unknown time zones but
65 * requires your RTC not to be off by more than 15 minutes
67 real_seconds = nowtime % 60;
68 real_minutes = nowtime / 60;
69 if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1)
70 real_minutes += 30; /* correct for half hour time zone */
71 real_minutes %= 60;
73 if (abs(real_minutes - cmos_minutes) < 30) {
74 BIN_TO_BCD(real_seconds);
75 BIN_TO_BCD(real_minutes);
76 rtc->control |= M48T35_RTC_SET;
77 rtc->sec = real_seconds;
78 rtc->min = real_minutes;
79 rtc->control &= ~M48T35_RTC_SET;
80 } else {
81 printk(KERN_WARNING
82 "set_rtc_mmss: can't update from %d to %d\n",
83 cmos_minutes, real_minutes);
84 retval = -1;
87 return retval;
90 void rt_timer_interrupt(struct pt_regs *regs)
92 int cpu = smp_processor_id();
93 int cpuA = ((cputoslice(cpu)) == 0);
94 int irq = 7; /* XXX Assign number */
96 write_lock(&xtime_lock);
98 again:
99 LOCAL_HUB_S(cpuA ? PI_RT_PEND_A : PI_RT_PEND_B, 0); /* Ack */
100 ct_cur[cpu] += CYCLES_PER_JIFFY;
101 LOCAL_HUB_S(cpuA ? PI_RT_COMPARE_A : PI_RT_COMPARE_B, ct_cur[cpu]);
103 if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur[cpu])
104 goto again;
106 kstat.irqs[cpu][irq]++; /* kstat only for bootcpu? */
108 if (cpu == 0)
109 do_timer(regs);
111 #ifdef CONFIG_SMP
113 int user = user_mode(regs);
116 * update_process_times() expects us to have done irq_enter().
117 * Besides, if we don't timer interrupts ignore the global
118 * interrupt lock, which is the WrongThing (tm) to do.
119 * Picked from i386 code.
121 irq_enter(cpu, 0);
122 update_process_times(user);
123 irq_exit(cpu, 0);
125 #endif /* CONFIG_SMP */
128 * If we have an externally synchronized Linux clock, then update
129 * RTC clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
130 * called as close as possible to when a second starts.
132 if ((time_status & STA_UNSYNC) == 0 &&
133 xtime.tv_sec > last_rtc_update + 660) {
134 if (xtime.tv_usec >= 1000000 - ((unsigned) tick) / 2) {
135 if (set_rtc_mmss(xtime.tv_sec + 1) == 0)
136 last_rtc_update = xtime.tv_sec;
137 else
138 last_rtc_update = xtime.tv_sec - 600;
139 } else if (xtime.tv_usec <= ((unsigned) tick) / 2) {
140 if (set_rtc_mmss(xtime.tv_sec) == 0)
141 last_rtc_update = xtime.tv_sec;
142 else
143 last_rtc_update = xtime.tv_sec - 600;
147 write_unlock(&xtime_lock);
150 unsigned long inline do_gettimeoffset(void)
152 unsigned long ct_cur1;
153 ct_cur1 = REMOTE_HUB_L(cputonasid(0), PI_RT_COUNT) + CYCLES_PER_JIFFY;
154 return (ct_cur1 - ct_cur[0]) * NSEC_PER_CYCLE / 1000;
157 void do_gettimeofday(struct timeval *tv)
159 unsigned long flags;
160 unsigned long usec, sec;
162 read_lock_irqsave(&xtime_lock, flags);
163 usec = do_gettimeoffset();
165 unsigned long lost = jiffies - wall_jiffies;
166 if (lost)
167 usec += lost * (1000000 / HZ);
169 sec = xtime.tv_sec;
170 usec += xtime.tv_usec;
171 read_unlock_irqrestore(&xtime_lock, flags);
173 while (usec >= 1000000) {
174 usec -= 1000000;
175 sec++;
178 tv->tv_sec = sec;
179 tv->tv_usec = usec;
182 void do_settimeofday(struct timeval *tv)
184 write_lock_irq(&xtime_lock);
185 tv->tv_usec -= do_gettimeoffset();
186 tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
188 while (tv->tv_usec < 0) {
189 tv->tv_usec += 1000000;
190 tv->tv_sec--;
193 xtime = *tv;
194 time_adjust = 0; /* stop active adjtime() */
195 time_status |= STA_UNSYNC;
196 time_maxerror = NTP_PHASE_LIMIT;
197 time_esterror = NTP_PHASE_LIMIT;
198 write_unlock_irq(&xtime_lock);
201 /* Includes for ioc3_init(). */
202 #include <asm/sn/types.h>
203 #include <asm/sn/sn0/addrs.h>
204 #include <asm/sn/sn0/hubni.h>
205 #include <asm/sn/sn0/hubio.h>
206 #include <asm/pci/bridge.h>
208 static __init unsigned long get_m48t35_time(void)
210 unsigned int year, month, date, hour, min, sec;
211 struct m48t35_rtc *rtc;
212 nasid_t nid;
214 nid = get_nasid();
215 rtc = (struct m48t35_rtc *)(KL_CONFIG_CH_CONS_INFO(nid)->memory_base +
216 IOC3_BYTEBUS_DEV0);
218 rtc->control |= M48T35_RTC_READ;
219 sec = rtc->sec;
220 min = rtc->min;
221 hour = rtc->hour;
222 date = rtc->date;
223 month = rtc->month;
224 year = rtc->year;
225 rtc->control &= ~M48T35_RTC_READ;
227 BCD_TO_BIN(sec);
228 BCD_TO_BIN(min);
229 BCD_TO_BIN(hour);
230 BCD_TO_BIN(date);
231 BCD_TO_BIN(month);
232 BCD_TO_BIN(year);
234 year += 1970;
236 return mktime(year, month, date, hour, min, sec);
239 void __init time_init(void)
241 xtime.tv_sec = get_m48t35_time();
242 xtime.tv_usec = 0;
245 void __init cpu_time_init(void)
247 lboard_t *board;
248 klcpu_t *cpu;
249 int cpuid;
251 /* Don't use ARCS. ARCS is fragile. Klconfig is simple and sane. */
252 board = find_lboard(KL_CONFIG_INFO(get_nasid()), KLTYPE_IP27);
253 if (!board)
254 panic("Can't find board info for myself.");
256 cpuid = LOCAL_HUB_L(PI_CPU_NUM) ? IP27_CPU0_INDEX : IP27_CPU1_INDEX;
257 cpu = (klcpu_t *) KLCF_COMP(board, cpuid);
258 if (!cpu)
259 panic("No information about myself?");
261 printk("CPU %d clock is %dMHz.\n", smp_processor_id(), cpu->cpu_speed);
263 set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK);
266 void __init hub_rtc_init(cnodeid_t cnode)
269 * We only need to initialize the current node.
270 * If this is not the current node then it is a cpuless
271 * node and timeouts will not happen there.
273 if (get_compact_nodeid() == cnode) {
274 int cpu = smp_processor_id();
275 LOCAL_HUB_S(PI_RT_EN_A, 1);
276 LOCAL_HUB_S(PI_RT_EN_B, 1);
277 LOCAL_HUB_S(PI_PROF_EN_A, 0);
278 LOCAL_HUB_S(PI_PROF_EN_B, 0);
279 ct_cur[cpu] = CYCLES_PER_JIFFY;
280 LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur[cpu]);
281 LOCAL_HUB_S(PI_RT_COUNT, 0);
282 LOCAL_HUB_S(PI_RT_PEND_A, 0);
283 LOCAL_HUB_S(PI_RT_COMPARE_B, ct_cur[cpu]);
284 LOCAL_HUB_S(PI_RT_COUNT, 0);
285 LOCAL_HUB_S(PI_RT_PEND_B, 0);