1 // SPDX-License-Identifier: GPL-2.0
3 * Support for periodic interrupts (100 per second) and for getting
4 * the current time from the RTC on Power Macintoshes.
6 * We use the decrementer register for our periodic interrupts.
8 * Paul Mackerras August 1996.
9 * Copyright (C) 1996 Paul Mackerras.
10 * Copyright (C) 2003-2005 Benjamin Herrenschmidt.
13 #include <linux/errno.h>
14 #include <linux/sched.h>
15 #include <linux/kernel.h>
16 #include <linux/param.h>
17 #include <linux/string.h>
19 #include <linux/init.h>
20 #include <linux/time.h>
21 #include <linux/adb.h>
22 #include <linux/cuda.h>
23 #include <linux/pmu.h>
24 #include <linux/interrupt.h>
25 #include <linux/hardirq.h>
26 #include <linux/rtc.h>
28 #include <asm/sections.h>
31 #include <asm/pgtable.h>
32 #include <asm/machdep.h>
34 #include <asm/nvram.h>
40 #define DBG(x...) printk(x)
46 * Offset between Unix time (1970-based) and Mac time (1904-based). Cuda and PMU
47 * times wrap in 2040. If we need to handle later times, the read_time functions
48 * need to be changed to interpret wrapped times as post-2040.
50 #define RTC_OFFSET 2082844800
53 * Calibrate the decrementer frequency with the VIA timer 1.
55 #define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
58 #define RS 0x200 /* skip between registers */
59 #define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
60 #define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
61 #define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
62 #define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
63 #define ACR (11*RS) /* Auxiliary control register */
64 #define IFR (13*RS) /* Interrupt flag register */
67 #define T1MODE 0xc0 /* Timer 1 mode */
68 #define T1MODE_CONT 0x40 /* continuous interrupts */
70 /* Bits in IFR and IER */
71 #define T1_INT 0x40 /* Timer 1 interrupt */
73 long __init pmac_time_init(void)
79 delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
80 delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
81 delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
82 if (delta & 0x00800000UL)
83 delta |= 0xFF000000UL;
84 dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
85 printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
91 #ifdef CONFIG_ADB_CUDA
92 static time64_t cuda_get_time(void)
94 struct adb_request req;
97 if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
101 if (req.reply_len != 7)
102 printk(KERN_ERR "cuda_get_time: got %d byte reply\n",
104 now = (u32)((req.reply[3] << 24) + (req.reply[4] << 16) +
105 (req.reply[5] << 8) + req.reply[6]);
106 /* it's either after year 2040, or the RTC has gone backwards */
107 WARN_ON(now < RTC_OFFSET);
109 return now - RTC_OFFSET;
112 #define cuda_get_rtc_time(tm) rtc_time64_to_tm(cuda_get_time(), (tm))
114 static int cuda_set_rtc_time(struct rtc_time *tm)
117 struct adb_request req;
119 nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
120 if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
121 nowtime >> 24, nowtime >> 16, nowtime >> 8,
124 while (!req.complete)
126 if ((req.reply_len != 3) && (req.reply_len != 7))
127 printk(KERN_ERR "cuda_set_rtc_time: got %d byte reply\n",
133 #define cuda_get_time() 0
134 #define cuda_get_rtc_time(tm)
135 #define cuda_set_rtc_time(tm) 0
138 #ifdef CONFIG_ADB_PMU
139 static time64_t pmu_get_time(void)
141 struct adb_request req;
144 if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
146 pmu_wait_complete(&req);
147 if (req.reply_len != 4)
148 printk(KERN_ERR "pmu_get_time: got %d byte reply from PMU\n",
150 now = (u32)((req.reply[0] << 24) + (req.reply[1] << 16) +
151 (req.reply[2] << 8) + req.reply[3]);
153 /* it's either after year 2040, or the RTC has gone backwards */
154 WARN_ON(now < RTC_OFFSET);
156 return now - RTC_OFFSET;
159 #define pmu_get_rtc_time(tm) rtc_time64_to_tm(pmu_get_time(), (tm))
161 static int pmu_set_rtc_time(struct rtc_time *tm)
164 struct adb_request req;
166 nowtime = lower_32_bits(rtc_tm_to_time64(tm) + RTC_OFFSET);
167 if (pmu_request(&req, NULL, 5, PMU_SET_RTC, nowtime >> 24,
168 nowtime >> 16, nowtime >> 8, nowtime) < 0)
170 pmu_wait_complete(&req);
171 if (req.reply_len != 0)
172 printk(KERN_ERR "pmu_set_rtc_time: %d byte reply from PMU\n",
178 #define pmu_get_time() 0
179 #define pmu_get_rtc_time(tm)
180 #define pmu_set_rtc_time(tm) 0
183 #ifdef CONFIG_PMAC_SMU
184 static time64_t smu_get_time(void)
188 if (smu_get_rtc_time(&tm, 1))
190 return rtc_tm_to_time64(&tm);
194 #define smu_get_time() 0
195 #define smu_get_rtc_time(tm, spin)
196 #define smu_set_rtc_time(tm, spin) 0
199 /* Can't be __init, it's called when suspending and resuming */
200 time64_t pmac_get_boot_time(void)
202 /* Get the time from the RTC, used only at boot time */
203 switch (sys_ctrler) {
204 case SYS_CTRLER_CUDA:
205 return cuda_get_time();
207 return pmu_get_time();
209 return smu_get_time();
215 void pmac_get_rtc_time(struct rtc_time *tm)
217 /* Get the time from the RTC, used only at boot time */
218 switch (sys_ctrler) {
219 case SYS_CTRLER_CUDA:
220 cuda_get_rtc_time(tm);
223 pmu_get_rtc_time(tm);
226 smu_get_rtc_time(tm, 1);
233 int pmac_set_rtc_time(struct rtc_time *tm)
235 switch (sys_ctrler) {
236 case SYS_CTRLER_CUDA:
237 return cuda_set_rtc_time(tm);
239 return pmu_set_rtc_time(tm);
241 return smu_set_rtc_time(tm, 1);
249 * Calibrate the decrementer register using VIA timer 1.
250 * This is used both on powermacs and CHRP machines.
252 int __init via_calibrate_decr(void)
254 struct device_node *vias;
255 volatile unsigned char __iomem *via;
256 int count = VIA_TIMER_FREQ_6 / 100;
257 unsigned int dstart, dend;
258 struct resource rsrc;
260 vias = of_find_node_by_name(NULL, "via-cuda");
262 vias = of_find_node_by_name(NULL, "via-pmu");
264 vias = of_find_node_by_name(NULL, "via");
265 if (vias == NULL || of_address_to_resource(vias, 0, &rsrc)) {
270 via = ioremap(rsrc.start, resource_size(&rsrc));
272 printk(KERN_ERR "Failed to map VIA for timer calibration !\n");
276 /* set timer 1 for continuous interrupts */
277 out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
278 /* set the counter to a small value */
279 out_8(&via[T1CH], 2);
280 /* set the latch to `count' */
281 out_8(&via[T1LL], count);
282 out_8(&via[T1LH], count >> 8);
283 /* wait until it hits 0 */
284 while ((in_8(&via[IFR]) & T1_INT) == 0)
287 /* clear the interrupt & wait until it hits 0 again */
289 while ((in_8(&via[IFR]) & T1_INT) == 0)
293 ppc_tb_freq = (dstart - dend) * 100 / 6;
302 * Query the OF and get the decr frequency.
304 void __init pmac_calibrate_decr(void)
306 generic_calibrate_decr();
309 /* We assume MacRISC2 machines have correct device-tree
310 * calibration. That's better since the VIA itself seems
311 * to be slightly off. --BenH
313 if (!of_machine_is_compatible("MacRISC2") &&
314 !of_machine_is_compatible("MacRISC3") &&
315 !of_machine_is_compatible("MacRISC4"))
316 if (via_calibrate_decr())
319 /* Special case: QuickSilver G4s seem to have a badly calibrated
320 * timebase-frequency in OF, VIA is much better on these. We should
321 * probably implement calibration based on the KL timer on these
322 * machines anyway... -BenH
324 if (of_machine_is_compatible("PowerMac3,5"))
325 if (via_calibrate_decr())