2 * BK Id: SCCS/s.prep_time.c 1.14 08/13/02 21:52:55 paulus
5 * arch/ppc/platforms/prep_time.c
7 * Copyright (C) 1991, 1992, 1995 Linus Torvalds
9 * Adapted for PowerPC (PReP) by Gary Thomas
10 * Modified by Cort Dougan (cort@cs.nmt.edu).
11 * Copied and modified from arch/i386/kernel/time.c
14 #include <linux/errno.h>
15 #include <linux/sched.h>
16 #include <linux/kernel.h>
17 #include <linux/param.h>
18 #include <linux/string.h>
20 #include <linux/interrupt.h>
21 #include <linux/time.h>
22 #include <linux/timex.h>
23 #include <linux/kernel_stat.h>
24 #include <linux/init.h>
26 #include <asm/sections.h>
27 #include <asm/segment.h>
29 #include <asm/processor.h>
30 #include <asm/machdep.h>
31 #include <asm/prep_nvram.h>
32 #include <asm/mk48t59.h>
36 extern spinlock_t rtc_lock;
39 * The motorola uses the m48t18 rtc (includes DS1643) whose registers
40 * are at a higher end of nvram (1ff8-1fff) than the ibm mc146818
41 * rtc (ds1386) which has regs at addr 0-d). The intel gets
42 * past this because the bios emulates the mc146818.
44 * Why in the world did they have to use different clocks?
46 * Right now things are hacked to check which machine we're on then
47 * use the appropriate macro. This is very very ugly and I should
48 * probably have a function that checks which machine we're on then
49 * does things correctly transparently or a function pointer which
50 * is setup at boot time to use the correct addresses.
55 * Set the hardware clock. -- Cort
58 int mc146818_set_rtc_time(unsigned long nowtime)
60 unsigned char save_control, save_freq_select;
66 /* tell the clock it's being set */
67 save_control = CMOS_READ(RTC_CONTROL);
69 CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL);
71 /* stop and reset prescaler */
72 save_freq_select = CMOS_READ(RTC_FREQ_SELECT);
74 CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT);
76 tm.tm_year = (tm.tm_year - 1900) % 100;
77 if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
78 BIN_TO_BCD(tm.tm_sec);
79 BIN_TO_BCD(tm.tm_min);
80 BIN_TO_BCD(tm.tm_hour);
81 BIN_TO_BCD(tm.tm_mon);
82 BIN_TO_BCD(tm.tm_mday);
83 BIN_TO_BCD(tm.tm_year);
85 CMOS_WRITE(tm.tm_sec, RTC_SECONDS);
86 CMOS_WRITE(tm.tm_min, RTC_MINUTES);
87 CMOS_WRITE(tm.tm_hour, RTC_HOURS);
88 CMOS_WRITE(tm.tm_mon, RTC_MONTH);
89 CMOS_WRITE(tm.tm_mday, RTC_DAY_OF_MONTH);
90 CMOS_WRITE(tm.tm_year, RTC_YEAR);
92 /* The following flags have to be released exactly in this order,
93 * otherwise the DS12887 (popular MC146818A clone with integrated
94 * battery and quartz) will not reset the oscillator and will not
95 * update precisely 500 ms later. You won't find this mentioned in
96 * the Dallas Semiconductor data sheets, but who believes data
97 * sheets anyway ... -- Markus Kuhn
99 CMOS_WRITE(save_control, RTC_CONTROL);
100 CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT);
101 spin_unlock(&rtc_lock);
107 unsigned long mc146818_get_rtc_time(void)
109 unsigned int year, mon, day, hour, min, sec;
112 /* The Linux interpretation of the CMOS clock register contents:
113 * When the Update-In-Progress (UIP) flag goes from 1 to 0, the
114 * RTC registers show the second which has precisely just started.
115 * Let's hope other operating systems interpret the RTC the same way.
118 /* Since the UIP flag is set for about 2.2 ms and the clock
119 * is typically written with a precision of 1 jiffy, trying
120 * to obtain a precision better than a few milliseconds is
121 * an illusion. Only consistency is interesting, this also
122 * allows to use the routine for /dev/rtc without a potential
123 * 1 second kernel busy loop triggered by any reader of /dev/rtc.
126 for ( i = 0; i<1000000; i++) {
127 uip = CMOS_READ(RTC_FREQ_SELECT);
128 sec = CMOS_READ(RTC_SECONDS);
129 min = CMOS_READ(RTC_MINUTES);
130 hour = CMOS_READ(RTC_HOURS);
131 day = CMOS_READ(RTC_DAY_OF_MONTH);
132 mon = CMOS_READ(RTC_MONTH);
133 year = CMOS_READ(RTC_YEAR);
134 uip |= CMOS_READ(RTC_FREQ_SELECT);
135 if ((uip & RTC_UIP)==0) break;
138 if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY)
148 if ((year += 1900) < 1970)
150 return mktime(year, mon, day, hour, min, sec);
154 int mk48t59_set_rtc_time(unsigned long nowtime)
156 unsigned char save_control;
159 spin_lock(&rtc_lock);
162 /* tell the clock it's being written */
163 save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
165 ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
166 (save_control | MK48T59_RTC_CA_WRITE));
168 tm.tm_year = (tm.tm_year - 1900) % 100;
169 BIN_TO_BCD(tm.tm_sec);
170 BIN_TO_BCD(tm.tm_min);
171 BIN_TO_BCD(tm.tm_hour);
172 BIN_TO_BCD(tm.tm_mon);
173 BIN_TO_BCD(tm.tm_mday);
174 BIN_TO_BCD(tm.tm_year);
176 ppc_md.nvram_write_val(MK48T59_RTC_SECONDS, tm.tm_sec);
177 ppc_md.nvram_write_val(MK48T59_RTC_MINUTES, tm.tm_min);
178 ppc_md.nvram_write_val(MK48T59_RTC_HOURS, tm.tm_hour);
179 ppc_md.nvram_write_val(MK48T59_RTC_MONTH, tm.tm_mon);
180 ppc_md.nvram_write_val(MK48T59_RTC_DAY_OF_MONTH, tm.tm_mday);
181 ppc_md.nvram_write_val(MK48T59_RTC_YEAR, tm.tm_year);
183 /* Turn off the write bit. */
184 ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
185 spin_unlock(&rtc_lock);
191 unsigned long mk48t59_get_rtc_time(void)
193 unsigned char save_control;
194 unsigned int year, mon, day, hour, min, sec;
196 /* Simple: freeze the clock, read it and allow updates again */
197 save_control = ppc_md.nvram_read_val(MK48T59_RTC_CONTROLA);
198 save_control &= ~MK48T59_RTC_CA_READ;
199 ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
201 /* Set the register to read the value. */
202 ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA,
203 (save_control | MK48T59_RTC_CA_READ));
205 sec = ppc_md.nvram_read_val(MK48T59_RTC_SECONDS);
206 min = ppc_md.nvram_read_val(MK48T59_RTC_MINUTES);
207 hour = ppc_md.nvram_read_val(MK48T59_RTC_HOURS);
208 day = ppc_md.nvram_read_val(MK48T59_RTC_DAY_OF_MONTH);
209 mon = ppc_md.nvram_read_val(MK48T59_RTC_MONTH);
210 year = ppc_md.nvram_read_val(MK48T59_RTC_YEAR);
212 /* Let the time values change again. */
213 ppc_md.nvram_write_val(MK48T59_RTC_CONTROLA, save_control);
227 return mktime(year, mon, day, hour, min, sec);