diff options
Diffstat (limited to 'arch/ppc/platforms/chrp_time.c')
-rw-r--r-- | arch/ppc/platforms/chrp_time.c | 235 |
1 files changed, 0 insertions, 235 deletions
diff --git a/arch/ppc/platforms/chrp_time.c b/arch/ppc/platforms/chrp_time.c deleted file mode 100644 index 51e06ad66168..000000000000 --- a/arch/ppc/platforms/chrp_time.c +++ /dev/null | |||
@@ -1,235 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1991, 1992, 1995 Linus Torvalds | ||
3 | * | ||
4 | * Adapted for PowerPC (PReP) by Gary Thomas | ||
5 | * Modified by Cort Dougan (cort@cs.nmt.edu). | ||
6 | * Copied and modified from arch/i386/kernel/time.c | ||
7 | * | ||
8 | */ | ||
9 | #include <linux/errno.h> | ||
10 | #include <linux/sched.h> | ||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/param.h> | ||
13 | #include <linux/string.h> | ||
14 | #include <linux/mm.h> | ||
15 | #include <linux/interrupt.h> | ||
16 | #include <linux/time.h> | ||
17 | #include <linux/timex.h> | ||
18 | #include <linux/kernel_stat.h> | ||
19 | #include <linux/mc146818rtc.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/bcd.h> | ||
22 | |||
23 | #include <asm/io.h> | ||
24 | #include <asm/nvram.h> | ||
25 | #include <asm/prom.h> | ||
26 | #include <asm/sections.h> | ||
27 | #include <asm/time.h> | ||
28 | |||
29 | extern spinlock_t rtc_lock; | ||
30 | |||
31 | static int nvram_as1 = NVRAM_AS1; | ||
32 | static int nvram_as0 = NVRAM_AS0; | ||
33 | static int nvram_data = NVRAM_DATA; | ||
34 | |||
35 | long __init chrp_time_init(void) | ||
36 | { | ||
37 | struct device_node *rtcs; | ||
38 | int base; | ||
39 | |||
40 | rtcs = find_compatible_devices("rtc", "pnpPNP,b00"); | ||
41 | if (rtcs == NULL) | ||
42 | rtcs = find_compatible_devices("rtc", "ds1385-rtc"); | ||
43 | if (rtcs == NULL || rtcs->addrs == NULL) | ||
44 | return 0; | ||
45 | base = rtcs->addrs[0].address; | ||
46 | nvram_as1 = 0; | ||
47 | nvram_as0 = base; | ||
48 | nvram_data = base + 1; | ||
49 | |||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | int chrp_cmos_clock_read(int addr) | ||
54 | { | ||
55 | if (nvram_as1 != 0) | ||
56 | outb(addr>>8, nvram_as1); | ||
57 | outb(addr, nvram_as0); | ||
58 | return (inb(nvram_data)); | ||
59 | } | ||
60 | |||
61 | void chrp_cmos_clock_write(unsigned long val, int addr) | ||
62 | { | ||
63 | if (nvram_as1 != 0) | ||
64 | outb(addr>>8, nvram_as1); | ||
65 | outb(addr, nvram_as0); | ||
66 | outb(val, nvram_data); | ||
67 | return; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * Set the hardware clock. -- Cort | ||
72 | */ | ||
73 | int chrp_set_rtc_time(unsigned long nowtime) | ||
74 | { | ||
75 | unsigned char save_control, save_freq_select; | ||
76 | struct rtc_time tm; | ||
77 | |||
78 | spin_lock(&rtc_lock); | ||
79 | to_tm(nowtime, &tm); | ||
80 | |||
81 | save_control = chrp_cmos_clock_read(RTC_CONTROL); /* tell the clock it's being set */ | ||
82 | |||
83 | chrp_cmos_clock_write((save_control|RTC_SET), RTC_CONTROL); | ||
84 | |||
85 | save_freq_select = chrp_cmos_clock_read(RTC_FREQ_SELECT); /* stop and reset prescaler */ | ||
86 | |||
87 | chrp_cmos_clock_write((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); | ||
88 | |||
89 | tm.tm_year -= 1900; | ||
90 | if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { | ||
91 | BIN_TO_BCD(tm.tm_sec); | ||
92 | BIN_TO_BCD(tm.tm_min); | ||
93 | BIN_TO_BCD(tm.tm_hour); | ||
94 | BIN_TO_BCD(tm.tm_mon); | ||
95 | BIN_TO_BCD(tm.tm_mday); | ||
96 | BIN_TO_BCD(tm.tm_year); | ||
97 | } | ||
98 | chrp_cmos_clock_write(tm.tm_sec,RTC_SECONDS); | ||
99 | chrp_cmos_clock_write(tm.tm_min,RTC_MINUTES); | ||
100 | chrp_cmos_clock_write(tm.tm_hour,RTC_HOURS); | ||
101 | chrp_cmos_clock_write(tm.tm_mon,RTC_MONTH); | ||
102 | chrp_cmos_clock_write(tm.tm_mday,RTC_DAY_OF_MONTH); | ||
103 | chrp_cmos_clock_write(tm.tm_year,RTC_YEAR); | ||
104 | |||
105 | /* The following flags have to be released exactly in this order, | ||
106 | * otherwise the DS12887 (popular MC146818A clone with integrated | ||
107 | * battery and quartz) will not reset the oscillator and will not | ||
108 | * update precisely 500 ms later. You won't find this mentioned in | ||
109 | * the Dallas Semiconductor data sheets, but who believes data | ||
110 | * sheets anyway ... -- Markus Kuhn | ||
111 | */ | ||
112 | chrp_cmos_clock_write(save_control, RTC_CONTROL); | ||
113 | chrp_cmos_clock_write(save_freq_select, RTC_FREQ_SELECT); | ||
114 | |||
115 | spin_unlock(&rtc_lock); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | unsigned long chrp_get_rtc_time(void) | ||
120 | { | ||
121 | unsigned int year, mon, day, hour, min, sec; | ||
122 | |||
123 | do { | ||
124 | sec = chrp_cmos_clock_read(RTC_SECONDS); | ||
125 | min = chrp_cmos_clock_read(RTC_MINUTES); | ||
126 | hour = chrp_cmos_clock_read(RTC_HOURS); | ||
127 | day = chrp_cmos_clock_read(RTC_DAY_OF_MONTH); | ||
128 | mon = chrp_cmos_clock_read(RTC_MONTH); | ||
129 | year = chrp_cmos_clock_read(RTC_YEAR); | ||
130 | } while (sec != chrp_cmos_clock_read(RTC_SECONDS)); | ||
131 | |||
132 | if (!(chrp_cmos_clock_read(RTC_CONTROL) & RTC_DM_BINARY) | ||
133 | || RTC_ALWAYS_BCD) { | ||
134 | BCD_TO_BIN(sec); | ||
135 | BCD_TO_BIN(min); | ||
136 | BCD_TO_BIN(hour); | ||
137 | BCD_TO_BIN(day); | ||
138 | BCD_TO_BIN(mon); | ||
139 | BCD_TO_BIN(year); | ||
140 | } | ||
141 | |||
142 | year += 1900; | ||
143 | if (year < 1970) | ||
144 | year += 100; | ||
145 | return mktime(year, mon, day, hour, min, sec); | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Calibrate the decrementer frequency with the VIA timer 1. | ||
150 | */ | ||
151 | #define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */ | ||
152 | |||
153 | /* VIA registers */ | ||
154 | #define RS 0x200 /* skip between registers */ | ||
155 | #define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */ | ||
156 | #define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */ | ||
157 | #define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */ | ||
158 | #define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */ | ||
159 | #define ACR (11*RS) /* Auxiliary control register */ | ||
160 | #define IFR (13*RS) /* Interrupt flag register */ | ||
161 | |||
162 | /* Bits in ACR */ | ||
163 | #define T1MODE 0xc0 /* Timer 1 mode */ | ||
164 | #define T1MODE_CONT 0x40 /* continuous interrupts */ | ||
165 | |||
166 | /* Bits in IFR and IER */ | ||
167 | #define T1_INT 0x40 /* Timer 1 interrupt */ | ||
168 | |||
169 | static int __init chrp_via_calibrate_decr(void) | ||
170 | { | ||
171 | struct device_node *vias; | ||
172 | volatile unsigned char __iomem *via; | ||
173 | int count = VIA_TIMER_FREQ_6 / 100; | ||
174 | unsigned int dstart, dend; | ||
175 | |||
176 | vias = find_devices("via-cuda"); | ||
177 | if (vias == 0) | ||
178 | vias = find_devices("via"); | ||
179 | if (vias == 0 || vias->n_addrs == 0) | ||
180 | return 0; | ||
181 | via = ioremap(vias->addrs[0].address, vias->addrs[0].size); | ||
182 | |||
183 | /* set timer 1 for continuous interrupts */ | ||
184 | out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT); | ||
185 | /* set the counter to a small value */ | ||
186 | out_8(&via[T1CH], 2); | ||
187 | /* set the latch to `count' */ | ||
188 | out_8(&via[T1LL], count); | ||
189 | out_8(&via[T1LH], count >> 8); | ||
190 | /* wait until it hits 0 */ | ||
191 | while ((in_8(&via[IFR]) & T1_INT) == 0) | ||
192 | ; | ||
193 | dstart = get_dec(); | ||
194 | /* clear the interrupt & wait until it hits 0 again */ | ||
195 | in_8(&via[T1CL]); | ||
196 | while ((in_8(&via[IFR]) & T1_INT) == 0) | ||
197 | ; | ||
198 | dend = get_dec(); | ||
199 | |||
200 | tb_ticks_per_jiffy = (dstart - dend) / ((6 * HZ)/100); | ||
201 | tb_to_us = mulhwu_scale_factor(dstart - dend, 60000); | ||
202 | |||
203 | printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n", | ||
204 | tb_ticks_per_jiffy, dstart - dend); | ||
205 | |||
206 | iounmap(via); | ||
207 | |||
208 | return 1; | ||
209 | } | ||
210 | |||
211 | void __init chrp_calibrate_decr(void) | ||
212 | { | ||
213 | struct device_node *cpu; | ||
214 | unsigned int freq, *fp; | ||
215 | |||
216 | if (chrp_via_calibrate_decr()) | ||
217 | return; | ||
218 | |||
219 | /* | ||
220 | * The cpu node should have a timebase-frequency property | ||
221 | * to tell us the rate at which the decrementer counts. | ||
222 | */ | ||
223 | freq = 16666000; /* hardcoded default */ | ||
224 | cpu = find_type_devices("cpu"); | ||
225 | if (cpu != 0) { | ||
226 | fp = (unsigned int *) | ||
227 | get_property(cpu, "timebase-frequency", NULL); | ||
228 | if (fp != 0) | ||
229 | freq = *fp; | ||
230 | } | ||
231 | printk("time_init: decrementer frequency = %u.%.6u MHz\n", | ||
232 | freq/1000000, freq%1000000); | ||
233 | tb_ticks_per_jiffy = freq / HZ; | ||
234 | tb_to_us = mulhwu_scale_factor(freq, 1000000); | ||
235 | } | ||