patch-2.1.51 linux/arch/ppc/kernel/pmac_time.c
Next file: linux/arch/ppc/kernel/port_io.c
Previous file: linux/arch/ppc/kernel/pmac_support.c
Back to the patch index
Back to the overall index
- Lines: 192
- Date:
Sat Aug 16 09:51:08 1997
- Orig file:
v2.1.50/linux/arch/ppc/kernel/pmac_time.c
- Orig date:
Mon Aug 4 16:25:36 1997
diff -u --recursive --new-file v2.1.50/linux/arch/ppc/kernel/pmac_time.c linux/arch/ppc/kernel/pmac_time.c
@@ -19,125 +19,60 @@
#include <asm/prom.h>
#include <asm/system.h>
-static int get_dec(void);
-static void set_dec(int);
-static unsigned long get_rtc_time(void);
+#include "time.h"
+
/* Apparently the RTC stores seconds since 1 Jan 1904 */
#define RTC_OFFSET 2082844800
-/* Accessor functions for the decrementer register. */
-static inline int
-get_dec()
-{
- int ret;
-
- asm volatile("mfspr %0,22" : "=r" (ret) :);
- return ret;
-}
-
-static inline void
-set_dec(int val)
-{
- asm volatile("mtspr 22,%0" : : "r" (val));
-}
-
-/* The decrementer counts down by 128 every 128ns on a 601. */
-#define DECREMENTER_COUNT_601 (1000000000 / HZ)
-#define COUNT_PERIOD_NUM_601 1
-#define COUNT_PERIOD_DEN_601 1000
-
-unsigned decrementer_count; /* count value for 1e6/HZ microseconds */
-unsigned count_period_num; /* 1 decrementer count equals */
-unsigned count_period_den; /* count_period_num / count_period_den us */
-
/*
- * This version of gettimeofday has microsecond resolution.
+ * Query the OF and get the decr frequency.
+ * This was taken from the pmac time_init() when merging the prep/pmac
+ * time functions.
*/
-void do_gettimeofday(struct timeval *tv)
-{
- unsigned long flags;
-
- save_flags(flags);
- cli();
- *tv = xtime;
- tv->tv_usec += (decrementer_count - get_dec())
- * count_period_num / count_period_den;
- if (tv->tv_usec >= 1000000) {
- tv->tv_usec -= 1000000;
- tv->tv_sec++;
- }
- restore_flags(flags);
-}
-
-void do_settimeofday(struct timeval *tv)
+void pmac_calibrate_decr(void)
{
- unsigned long flags;
- int frac_tick;
+ struct device_node *cpu;
+ int freq, *fp, divisor;
- frac_tick = tv->tv_usec % (1000000 / HZ);
- save_flags(flags);
- cli();
- xtime.tv_sec = tv->tv_sec;
- xtime.tv_usec = tv->tv_usec - frac_tick;
- set_dec(frac_tick * count_period_den / count_period_num);
- restore_flags(flags);
+ /*
+ * The cpu node should have a timebase-frequency property
+ * to tell us the rate at which the decrementer counts.
+ */
+ cpu = find_type_devices("cpu");
+ if (cpu == 0)
+ panic("can't find cpu node in time_init");
+ fp = (int *) get_property(cpu, "timebase-frequency", NULL);
+ if (fp == 0)
+ panic("can't get cpu timebase frequency");
+ freq = *fp * 60; /* try to make freq/1e6 an integer */
+ divisor = 60;
+ printk("time_init: decrementer frequency = %d/%d\n",
+ freq, divisor);
+ decrementer_count = freq / HZ / divisor;
+ count_period_num = divisor;
+ count_period_den = freq / 1000000;
}
-/*
- * timer_interrupt - gets called when the decrementer overflows,
- * with interrupts disabled.
- * We set it up to overflow again in 1/HZ seconds.
- */
-void timer_interrupt(struct pt_regs * regs)
+unsigned long
+pmac_get_rtc_time(void)
{
- int dval, d;
-
- while ((dval = get_dec()) < 0) {
- /*
- * Wait for the decrementer to change, then jump
- * in and add decrementer_count to its value
- * (quickly, before it changes again!)
- */
- while ((d = get_dec()) == dval)
- ;
- set_dec(d + decrementer_count);
- do_timer(regs);
- }
+ struct cuda_request req;
+ /* Get the time from the RTC */
+ cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME);
+ while (!req.got_reply)
+ cuda_poll();
+ if (req.reply_len != 7)
+ printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
+ req.reply_len);
+ return (req.reply[3] << 24) + (req.reply[4] << 16)
+ + (req.reply[5] << 8) + req.reply[6] - RTC_OFFSET;
}
-void
-time_init(void)
+int pmac_set_rtc_time(unsigned long nowtime)
{
- struct device_node *cpu;
- int freq, *fp, divisor;
-
- if ((_get_PVR() >> 16) == 1) {
- /* 601 processor: dec counts down by 128 every 128ns */
- decrementer_count = DECREMENTER_COUNT_601;
- count_period_num = COUNT_PERIOD_NUM_601;
- count_period_den = COUNT_PERIOD_DEN_601;
- } else {
- /*
- * The cpu node should have a timebase-frequency property
- * to tell us the rate at which the decrementer counts.
- */
- cpu = find_type_devices("cpu");
- if (cpu == 0)
- panic("can't find cpu node in time_init");
- fp = (int *) get_property(cpu, "timebase-frequency", NULL);
- if (fp == 0)
- panic("can't get cpu timebase frequency");
- freq = *fp * 60; /* try to make freq/1e6 an integer */
- divisor = 60;
- printk("time_init: decrementer frequency = %d/%d\n",
- freq, divisor);
- decrementer_count = freq / HZ / divisor;
- count_period_num = divisor;
- count_period_den = freq / 1000000;
- }
- set_dec(decrementer_count);
+ return 0;
}
/*
@@ -145,24 +80,8 @@
* been called at that stage.
*/
void
-read_rtc_time(void)
+pmac_read_rtc_time(void)
{
- xtime.tv_sec = get_rtc_time();
+ xtime.tv_sec = pmac_get_rtc_time();
xtime.tv_usec = 0;
-}
-
-static unsigned long
-get_rtc_time()
-{
- struct cuda_request req;
-
- /* Get the time from the RTC */
- cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME);
- while (!req.got_reply)
- cuda_poll();
- if (req.reply_len != 7)
- panic("get_rtc_time: didn't expect %d byte reply",
- req.reply_len);
- return (req.reply[3] << 24) + (req.reply[4] << 16)
- + (req.reply[5] << 8) + req.reply[6] - RTC_OFFSET;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov