pmac_time.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. /*
  2. * Support for periodic interrupts (100 per second) and for getting
  3. * the current time from the RTC on Power Macintoshes.
  4. *
  5. * We use the decrementer register for our periodic interrupts.
  6. *
  7. * Paul Mackerras August 1996.
  8. * Copyright (C) 1996 Paul Mackerras.
  9. */
  10. #include <linux/config.h>
  11. #include <linux/errno.h>
  12. #include <linux/sched.h>
  13. #include <linux/kernel.h>
  14. #include <linux/param.h>
  15. #include <linux/string.h>
  16. #include <linux/mm.h>
  17. #include <linux/init.h>
  18. #include <linux/time.h>
  19. #include <linux/adb.h>
  20. #include <linux/cuda.h>
  21. #include <linux/pmu.h>
  22. #include <linux/hardirq.h>
  23. #include <asm/sections.h>
  24. #include <asm/prom.h>
  25. #include <asm/system.h>
  26. #include <asm/io.h>
  27. #include <asm/pgtable.h>
  28. #include <asm/machdep.h>
  29. #include <asm/time.h>
  30. #include <asm/nvram.h>
  31. /* Apparently the RTC stores seconds since 1 Jan 1904 */
  32. #define RTC_OFFSET 2082844800
  33. /*
  34. * Calibrate the decrementer frequency with the VIA timer 1.
  35. */
  36. #define VIA_TIMER_FREQ_6 4700000 /* time 1 frequency * 6 */
  37. /* VIA registers */
  38. #define RS 0x200 /* skip between registers */
  39. #define T1CL (4*RS) /* Timer 1 ctr/latch (low 8 bits) */
  40. #define T1CH (5*RS) /* Timer 1 counter (high 8 bits) */
  41. #define T1LL (6*RS) /* Timer 1 latch (low 8 bits) */
  42. #define T1LH (7*RS) /* Timer 1 latch (high 8 bits) */
  43. #define ACR (11*RS) /* Auxiliary control register */
  44. #define IFR (13*RS) /* Interrupt flag register */
  45. /* Bits in ACR */
  46. #define T1MODE 0xc0 /* Timer 1 mode */
  47. #define T1MODE_CONT 0x40 /* continuous interrupts */
  48. /* Bits in IFR and IER */
  49. #define T1_INT 0x40 /* Timer 1 interrupt */
  50. extern struct timezone sys_tz;
  51. long __init
  52. pmac_time_init(void)
  53. {
  54. #ifdef CONFIG_NVRAM
  55. s32 delta = 0;
  56. int dst;
  57. delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
  58. delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
  59. delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
  60. if (delta & 0x00800000UL)
  61. delta |= 0xFF000000UL;
  62. dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
  63. printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
  64. dst ? "on" : "off");
  65. return delta;
  66. #else
  67. return 0;
  68. #endif
  69. }
  70. unsigned long __pmac
  71. pmac_get_rtc_time(void)
  72. {
  73. #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
  74. struct adb_request req;
  75. unsigned long now;
  76. #endif
  77. /* Get the time from the RTC */
  78. switch (sys_ctrler) {
  79. #ifdef CONFIG_ADB_CUDA
  80. case SYS_CTRLER_CUDA:
  81. if (cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_GET_TIME) < 0)
  82. return 0;
  83. while (!req.complete)
  84. cuda_poll();
  85. if (req.reply_len != 7)
  86. printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
  87. req.reply_len);
  88. now = (req.reply[3] << 24) + (req.reply[4] << 16)
  89. + (req.reply[5] << 8) + req.reply[6];
  90. return now - RTC_OFFSET;
  91. #endif /* CONFIG_ADB_CUDA */
  92. #ifdef CONFIG_ADB_PMU
  93. case SYS_CTRLER_PMU:
  94. if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0)
  95. return 0;
  96. while (!req.complete)
  97. pmu_poll();
  98. if (req.reply_len != 4)
  99. printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
  100. req.reply_len);
  101. now = (req.reply[0] << 24) + (req.reply[1] << 16)
  102. + (req.reply[2] << 8) + req.reply[3];
  103. return now - RTC_OFFSET;
  104. #endif /* CONFIG_ADB_PMU */
  105. default: ;
  106. }
  107. return 0;
  108. }
  109. int __pmac
  110. pmac_set_rtc_time(unsigned long nowtime)
  111. {
  112. #if defined(CONFIG_ADB_CUDA) || defined(CONFIG_ADB_PMU)
  113. struct adb_request req;
  114. #endif
  115. nowtime += RTC_OFFSET;
  116. switch (sys_ctrler) {
  117. #ifdef CONFIG_ADB_CUDA
  118. case SYS_CTRLER_CUDA:
  119. if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
  120. nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
  121. return 0;
  122. while (!req.complete)
  123. cuda_poll();
  124. if ((req.reply_len != 3) && (req.reply_len != 7))
  125. printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
  126. req.reply_len);
  127. return 1;
  128. #endif /* CONFIG_ADB_CUDA */
  129. #ifdef CONFIG_ADB_PMU
  130. case SYS_CTRLER_PMU:
  131. if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
  132. nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
  133. return 0;
  134. while (!req.complete)
  135. pmu_poll();
  136. if (req.reply_len != 0)
  137. printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
  138. req.reply_len);
  139. return 1;
  140. #endif /* CONFIG_ADB_PMU */
  141. default:
  142. return 0;
  143. }
  144. }
  145. /*
  146. * Calibrate the decrementer register using VIA timer 1.
  147. * This is used both on powermacs and CHRP machines.
  148. */
  149. int __init
  150. via_calibrate_decr(void)
  151. {
  152. struct device_node *vias;
  153. volatile unsigned char __iomem *via;
  154. int count = VIA_TIMER_FREQ_6 / 100;
  155. unsigned int dstart, dend;
  156. vias = find_devices("via-cuda");
  157. if (vias == 0)
  158. vias = find_devices("via-pmu");
  159. if (vias == 0)
  160. vias = find_devices("via");
  161. if (vias == 0 || vias->n_addrs == 0)
  162. return 0;
  163. via = ioremap(vias->addrs[0].address, vias->addrs[0].size);
  164. /* set timer 1 for continuous interrupts */
  165. out_8(&via[ACR], (via[ACR] & ~T1MODE) | T1MODE_CONT);
  166. /* set the counter to a small value */
  167. out_8(&via[T1CH], 2);
  168. /* set the latch to `count' */
  169. out_8(&via[T1LL], count);
  170. out_8(&via[T1LH], count >> 8);
  171. /* wait until it hits 0 */
  172. while ((in_8(&via[IFR]) & T1_INT) == 0)
  173. ;
  174. dstart = get_dec();
  175. /* clear the interrupt & wait until it hits 0 again */
  176. in_8(&via[T1CL]);
  177. while ((in_8(&via[IFR]) & T1_INT) == 0)
  178. ;
  179. dend = get_dec();
  180. tb_ticks_per_jiffy = (dstart - dend) / (6 * (HZ/100));
  181. tb_to_us = mulhwu_scale_factor(dstart - dend, 60000);
  182. printk(KERN_INFO "via_calibrate_decr: ticks per jiffy = %u (%u ticks)\n",
  183. tb_ticks_per_jiffy, dstart - dend);
  184. iounmap(via);
  185. return 1;
  186. }
  187. #ifdef CONFIG_PM
  188. /*
  189. * Reset the time after a sleep.
  190. */
  191. static int __pmac
  192. time_sleep_notify(struct pmu_sleep_notifier *self, int when)
  193. {
  194. static unsigned long time_diff;
  195. unsigned long flags;
  196. unsigned long seq;
  197. switch (when) {
  198. case PBOOK_SLEEP_NOW:
  199. do {
  200. seq = read_seqbegin_irqsave(&xtime_lock, flags);
  201. time_diff = xtime.tv_sec - pmac_get_rtc_time();
  202. } while (read_seqretry_irqrestore(&xtime_lock, seq, flags));
  203. break;
  204. case PBOOK_WAKE:
  205. write_seqlock_irqsave(&xtime_lock, flags);
  206. xtime.tv_sec = pmac_get_rtc_time() + time_diff;
  207. xtime.tv_nsec = 0;
  208. last_rtc_update = xtime.tv_sec;
  209. write_sequnlock_irqrestore(&xtime_lock, flags);
  210. break;
  211. }
  212. return PBOOK_SLEEP_OK;
  213. }
  214. static struct pmu_sleep_notifier time_sleep_notifier __pmacdata = {
  215. time_sleep_notify, SLEEP_LEVEL_MISC,
  216. };
  217. #endif /* CONFIG_PM */
  218. /*
  219. * Query the OF and get the decr frequency.
  220. * This was taken from the pmac time_init() when merging the prep/pmac
  221. * time functions.
  222. */
  223. void __init
  224. pmac_calibrate_decr(void)
  225. {
  226. struct device_node *cpu;
  227. unsigned int freq, *fp;
  228. #ifdef CONFIG_PM
  229. pmu_register_sleep_notifier(&time_sleep_notifier);
  230. #endif /* CONFIG_PM */
  231. /* We assume MacRISC2 machines have correct device-tree
  232. * calibration. That's better since the VIA itself seems
  233. * to be slightly off. --BenH
  234. */
  235. if (!machine_is_compatible("MacRISC2") &&
  236. !machine_is_compatible("MacRISC3") &&
  237. !machine_is_compatible("MacRISC4"))
  238. if (via_calibrate_decr())
  239. return;
  240. /* Special case: QuickSilver G4s seem to have a badly calibrated
  241. * timebase-frequency in OF, VIA is much better on these. We should
  242. * probably implement calibration based on the KL timer on these
  243. * machines anyway... -BenH
  244. */
  245. if (machine_is_compatible("PowerMac3,5"))
  246. if (via_calibrate_decr())
  247. return;
  248. /*
  249. * The cpu node should have a timebase-frequency property
  250. * to tell us the rate at which the decrementer counts.
  251. */
  252. cpu = find_type_devices("cpu");
  253. if (cpu == 0)
  254. panic("can't find cpu node in time_init");
  255. fp = (unsigned int *) get_property(cpu, "timebase-frequency", NULL);
  256. if (fp == 0)
  257. panic("can't get cpu timebase frequency");
  258. freq = *fp;
  259. printk("time_init: decrementer frequency = %u.%.6u MHz\n",
  260. freq/1000000, freq%1000000);
  261. tb_ticks_per_jiffy = freq / HZ;
  262. tb_to_us = mulhwu_scale_factor(freq, 1000000);
  263. }