summaryrefslogtreecommitdiffstats
path: root/arch/mips64/sgi-ip27/ip27-timer.c
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>2000-01-17 23:32:45 +0000
committerRalf Baechle <ralf@linux-mips.org>2000-01-17 23:32:45 +0000
commitbb382d1cd598a97151a0edf5ac26e36afb0a64ce (patch)
treefd9f0ca1b31e5af2faa0d7165e6fd0fbb5524ebf /arch/mips64/sgi-ip27/ip27-timer.c
parentaf38bda129551834653720f277a920d7d284bd3d (diff)
- IOC3 driver now will panic when encountering a RX/TX PCI DMA error.
- IOC3 driver does no longer use GFP_DMA which given the _very_ small number of available GFP_DMA pages might have deadlocked the system. - First cut of Origin support. Last minute change: Do no longer use ARC memory / MD hub memory configuration information but klconfig.h stuff. Simpler, faster, shorter. - Zillions of MIPS64 fixes.
Diffstat (limited to 'arch/mips64/sgi-ip27/ip27-timer.c')
-rw-r--r--arch/mips64/sgi-ip27/ip27-timer.c115
1 files changed, 115 insertions, 0 deletions
diff --git a/arch/mips64/sgi-ip27/ip27-timer.c b/arch/mips64/sgi-ip27/ip27-timer.c
new file mode 100644
index 000000000..e5fd6c377
--- /dev/null
+++ b/arch/mips64/sgi-ip27/ip27-timer.c
@@ -0,0 +1,115 @@
+/* $Id$
+ *
+ * Copytight (C) 1999 Ralf Baechle (ralf@gnu.org)
+ * Copytight (C) 1999 Silicon Graphics, Inc.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/param.h>
+#include <linux/timex.h>
+#include <linux/mm.h>
+
+#include <asm/pgtable.h>
+#include <asm/sgialib.h>
+#include <asm/sn/arch.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/sn0/ip27.h>
+#include <asm/sn/sn0/hub.h>
+
+/* This is a hack; we really need to figure these values out dynamically
+ *
+ * Since 800 ns works very well with various HUB frequencies, such as
+ * 360, 380, 390 and 400 MHZ, we use 800 ns rtc cycle time.
+ *
+ * Ralf: which clock rate is used to feed the counter?
+ */
+#define NSEC_PER_CYCLE 800
+#define NSEC_PER_SEC 1000000000
+#define CYCLES_PER_SEC (NSEC_PER_SEC/NSEC_PER_CYCLE)
+#define CYCLES_PER_JIFFY (CYCLES_PER_SEC/HZ)
+
+static unsigned long ct_cur; /* What counter should be at next timer irq */
+
+extern rwlock_t xtime_lock;
+
+void rt_timer_interrupt(struct pt_regs *regs)
+{
+ int irq = 7; /* XXX Assign number */
+
+ write_lock(&xtime_lock);
+
+again:
+ LOCAL_HUB_S(PI_RT_PEND_A, 0); /* Ack */
+ ct_cur += CYCLES_PER_JIFFY;
+ LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+
+ if (LOCAL_HUB_L(PI_RT_COUNT) >= ct_cur)
+ goto again;
+
+ kstat.irqs[0][irq]++;
+ do_timer(regs);
+
+ write_unlock(&xtime_lock);
+}
+
+void do_gettimeofday(struct timeval *tv)
+{
+ unsigned long flags;
+
+ read_lock_irqsave(&xtime_lock, flags);
+ *tv = xtime;
+ read_unlock_irqrestore(&xtime_lock, flags);
+}
+
+void do_settimeofday(struct timeval *tv)
+{
+ write_lock_irq(&xtime_lock);
+ xtime = *tv;
+ time_state = TIME_BAD;
+ time_maxerror = MAXPHASE;
+ time_esterror = MAXPHASE;
+ write_unlock_irq(&xtime_lock);
+}
+
+/* Includes for ioc3_init(). */
+#include <linux/init.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sn0/addrs.h>
+#include <asm/sn/sn0/hubni.h>
+#include <asm/sn/sn0/hubio.h>
+#include <asm/sn/klconfig.h>
+#include <asm/ioc3.h>
+#include <asm/pci/bridge.h>
+
+extern void ioc3_eth_init(void);
+
+void __init time_init(void)
+{
+ unsigned int cpufreq;
+ char *cpufreqstr;
+
+ /* Is this timesource good enough? Ok to assume that all CPUs have
+ this clockrate? Are they 100% synchronously clocked? */
+ cpufreqstr = ArcGetEnvironmentVariable("cpufreq");
+ if (cpufreqstr == NULL)
+ panic("Cannot detect CPU clock rate");
+ cpufreq = simple_strtoul(cpufreqstr, NULL, 10);
+ printk("PROM says CPU clock is %dMHz\n", cpufreq);
+
+ /* We didn't flush the TLB earlier since the ARC firmware depends on
+ it. So do it now. */
+ flush_tlb_all();
+
+ /* Don't worry about second CPU, it's disabled. */
+ LOCAL_HUB_S(PI_RT_EN_A, 1);
+ LOCAL_HUB_S(PI_PROF_EN_A, 0);
+ ct_cur = CYCLES_PER_JIFFY;
+ LOCAL_HUB_S(PI_RT_COMPARE_A, ct_cur);
+ LOCAL_HUB_S(PI_RT_COUNT, 0);
+ LOCAL_HUB_S(PI_RT_PEND_A, 0);
+
+ set_cp0_status(SRB_TIMOCLK, SRB_TIMOCLK);
+}