]> err.no Git - linux-2.6/blob - arch/x86/kernel/hpet_32.c
i386: prepare sharing the hpet code with x86_64
[linux-2.6] / arch / x86 / kernel / hpet_32.c
1 #include <linux/clocksource.h>
2 #include <linux/clockchips.h>
3 #include <linux/delay.h>
4 #include <linux/errno.h>
5 #include <linux/hpet.h>
6 #include <linux/init.h>
7 #include <linux/sysdev.h>
8 #include <linux/pm.h>
9 #include <linux/delay.h>
10
11 #include <asm/fixmap.h>
12 #include <asm/hpet.h>
13 #include <asm/i8253.h>
14 #include <asm/io.h>
15
16 #define HPET_MASK       CLOCKSOURCE_MASK(32)
17 #define HPET_SHIFT      22
18
19 /* FSEC = 10^-15 NSEC = 10^-9 */
20 #define FSEC_PER_NSEC   1000000
21
22 /*
23  * HPET address is set in acpi/boot.c, when an ACPI entry exists
24  */
25 unsigned long hpet_address;
26 static void __iomem *hpet_virt_address;
27
28 /* Temporary hack. Cleanup after x86_64 clock events conversion */
29 #undef hpet_readl
30 #undef hpet_writel
31
32 static inline unsigned long hpet_readl(unsigned long a)
33 {
34         return readl(hpet_virt_address + a);
35 }
36
37 static inline void hpet_writel(unsigned long d, unsigned long a)
38 {
39         writel(d, hpet_virt_address + a);
40 }
41
42 #ifdef CONFIG_X86_64
43
44 #include <asm/pgtable.h>
45
46 static inline void hpet_set_mapping(void)
47 {
48         set_fixmap_nocache(FIX_HPET_BASE, hpet_address);
49         __set_fixmap(VSYSCALL_HPET, hpet_address, PAGE_KERNEL_VSYSCALL_NOCACHE);
50         hpet_virt_address = (void __iomem *)fix_to_virt(FIX_HPET_BASE);
51 }
52
53 static inline void hpet_clear_mapping(void)
54 {
55         hpet_virt_address = NULL;
56 }
57
58 #else
59
60 static inline void hpet_set_mapping(void)
61 {
62         hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE);
63 }
64
65 static inline void hpet_clear_mapping(void)
66 {
67         iounmap(hpet_virt_address);
68         hpet_virt_address = NULL;
69 }
70 #endif
71
72 /*
73  * HPET command line enable / disable
74  */
75 static int boot_hpet_disable;
76
77 static int __init hpet_setup(char* str)
78 {
79         if (str) {
80                 if (!strncmp("disable", str, 7))
81                         boot_hpet_disable = 1;
82         }
83         return 1;
84 }
85 __setup("hpet=", hpet_setup);
86
87 static int __init disable_hpet(char *str)
88 {
89         boot_hpet_disable = 1;
90         return 1;
91 }
92 __setup("nohpet", disable_hpet);
93
94 static inline int is_hpet_capable(void)
95 {
96         return (!boot_hpet_disable && hpet_address);
97 }
98
99 /*
100  * HPET timer interrupt enable / disable
101  */
102 static int hpet_legacy_int_enabled;
103
104 /**
105  * is_hpet_enabled - check whether the hpet timer interrupt is enabled
106  */
107 int is_hpet_enabled(void)
108 {
109         return is_hpet_capable() && hpet_legacy_int_enabled;
110 }
111
112 /*
113  * When the hpet driver (/dev/hpet) is enabled, we need to reserve
114  * timer 0 and timer 1 in case of RTC emulation.
115  */
116 #ifdef CONFIG_HPET
117 static void hpet_reserve_platform_timers(unsigned long id)
118 {
119         struct hpet __iomem *hpet = hpet_virt_address;
120         struct hpet_timer __iomem *timer = &hpet->hpet_timers[2];
121         unsigned int nrtimers, i;
122         struct hpet_data hd;
123
124         nrtimers = ((id & HPET_ID_NUMBER) >> HPET_ID_NUMBER_SHIFT) + 1;
125
126         memset(&hd, 0, sizeof (hd));
127         hd.hd_phys_address = hpet_address;
128         hd.hd_address = hpet;
129         hd.hd_nirqs = nrtimers;
130         hd.hd_flags = HPET_DATA_PLATFORM;
131         hpet_reserve_timer(&hd, 0);
132
133 #ifdef CONFIG_HPET_EMULATE_RTC
134         hpet_reserve_timer(&hd, 1);
135 #endif
136
137         hd.hd_irq[0] = HPET_LEGACY_8254;
138         hd.hd_irq[1] = HPET_LEGACY_RTC;
139
140         for (i = 2; i < nrtimers; timer++, i++)
141                 hd.hd_irq[i] = (timer->hpet_config & Tn_INT_ROUTE_CNF_MASK) >>
142                         Tn_INT_ROUTE_CNF_SHIFT;
143
144         hpet_alloc(&hd);
145
146 }
147 #else
148 static void hpet_reserve_platform_timers(unsigned long id) { }
149 #endif
150
151 /*
152  * Common hpet info
153  */
154 static unsigned long hpet_period;
155
156 static void hpet_set_mode(enum clock_event_mode mode,
157                           struct clock_event_device *evt);
158 static int hpet_next_event(unsigned long delta,
159                            struct clock_event_device *evt);
160
161 /*
162  * The hpet clock event device
163  */
164 static struct clock_event_device hpet_clockevent = {
165         .name           = "hpet",
166         .features       = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
167         .set_mode       = hpet_set_mode,
168         .set_next_event = hpet_next_event,
169         .shift          = 32,
170         .irq            = 0,
171 };
172
173 static void hpet_start_counter(void)
174 {
175         unsigned long cfg = hpet_readl(HPET_CFG);
176
177         cfg &= ~HPET_CFG_ENABLE;
178         hpet_writel(cfg, HPET_CFG);
179         hpet_writel(0, HPET_COUNTER);
180         hpet_writel(0, HPET_COUNTER + 4);
181         cfg |= HPET_CFG_ENABLE;
182         hpet_writel(cfg, HPET_CFG);
183 }
184
185 static void hpet_enable_int(void)
186 {
187         unsigned long cfg = hpet_readl(HPET_CFG);
188
189         cfg |= HPET_CFG_LEGACY;
190         hpet_writel(cfg, HPET_CFG);
191         hpet_legacy_int_enabled = 1;
192 }
193
194 static void hpet_set_mode(enum clock_event_mode mode,
195                           struct clock_event_device *evt)
196 {
197         unsigned long cfg, cmp, now;
198         uint64_t delta;
199
200         switch(mode) {
201         case CLOCK_EVT_MODE_PERIODIC:
202                 delta = ((uint64_t)(NSEC_PER_SEC/HZ)) * hpet_clockevent.mult;
203                 delta >>= hpet_clockevent.shift;
204                 now = hpet_readl(HPET_COUNTER);
205                 cmp = now + (unsigned long) delta;
206                 cfg = hpet_readl(HPET_T0_CFG);
207                 cfg |= HPET_TN_ENABLE | HPET_TN_PERIODIC |
208                        HPET_TN_SETVAL | HPET_TN_32BIT;
209                 hpet_writel(cfg, HPET_T0_CFG);
210                 /*
211                  * The first write after writing TN_SETVAL to the
212                  * config register sets the counter value, the second
213                  * write sets the period.
214                  */
215                 hpet_writel(cmp, HPET_T0_CMP);
216                 udelay(1);
217                 hpet_writel((unsigned long) delta, HPET_T0_CMP);
218                 break;
219
220         case CLOCK_EVT_MODE_ONESHOT:
221                 cfg = hpet_readl(HPET_T0_CFG);
222                 cfg &= ~HPET_TN_PERIODIC;
223                 cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
224                 hpet_writel(cfg, HPET_T0_CFG);
225                 break;
226
227         case CLOCK_EVT_MODE_UNUSED:
228         case CLOCK_EVT_MODE_SHUTDOWN:
229                 cfg = hpet_readl(HPET_T0_CFG);
230                 cfg &= ~HPET_TN_ENABLE;
231                 hpet_writel(cfg, HPET_T0_CFG);
232                 break;
233
234         case CLOCK_EVT_MODE_RESUME:
235                 hpet_enable_int();
236                 break;
237         }
238 }
239
240 static int hpet_next_event(unsigned long delta,
241                            struct clock_event_device *evt)
242 {
243         unsigned long cnt;
244
245         cnt = hpet_readl(HPET_COUNTER);
246         cnt += delta;
247         hpet_writel(cnt, HPET_T0_CMP);
248
249         return ((long)(hpet_readl(HPET_COUNTER) - cnt ) > 0) ? -ETIME : 0;
250 }
251
252 /*
253  * Clock source related code
254  */
255 static cycle_t read_hpet(void)
256 {
257         return (cycle_t)hpet_readl(HPET_COUNTER);
258 }
259
260 #ifdef CONFIG_X86_64
261 static cycle_t __vsyscall_fn vread_hpet(void)
262 {
263         return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0);
264 }
265 #endif
266
267 static struct clocksource clocksource_hpet = {
268         .name           = "hpet",
269         .rating         = 250,
270         .read           = read_hpet,
271         .mask           = HPET_MASK,
272         .shift          = HPET_SHIFT,
273         .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
274         .resume         = hpet_start_counter,
275 #ifdef CONFIG_X86_64
276         .vread          = vread_hpet,
277 #endif
278 };
279
280 /*
281  * Try to setup the HPET timer
282  */
283 int __init hpet_enable(void)
284 {
285         unsigned long id;
286         uint64_t hpet_freq;
287         u64 tmp, start, now;
288         cycle_t t1;
289
290         if (!is_hpet_capable())
291                 return 0;
292
293         hpet_set_mapping();
294
295         /*
296          * Read the period and check for a sane value:
297          */
298         hpet_period = hpet_readl(HPET_PERIOD);
299         if (hpet_period < HPET_MIN_PERIOD || hpet_period > HPET_MAX_PERIOD)
300                 goto out_nohpet;
301
302         /*
303          * The period is a femto seconds value. We need to calculate the
304          * scaled math multiplication factor for nanosecond to hpet tick
305          * conversion.
306          */
307         hpet_freq = 1000000000000000ULL;
308         do_div(hpet_freq, hpet_period);
309         hpet_clockevent.mult = div_sc((unsigned long) hpet_freq,
310                                       NSEC_PER_SEC, 32);
311         /* Calculate the min / max delta */
312         hpet_clockevent.max_delta_ns = clockevent_delta2ns(0x7FFFFFFF,
313                                                            &hpet_clockevent);
314         hpet_clockevent.min_delta_ns = clockevent_delta2ns(0x30,
315                                                            &hpet_clockevent);
316
317         /*
318          * Read the HPET ID register to retrieve the IRQ routing
319          * information and the number of channels
320          */
321         id = hpet_readl(HPET_ID);
322
323 #ifdef CONFIG_HPET_EMULATE_RTC
324         /*
325          * The legacy routing mode needs at least two channels, tick timer
326          * and the rtc emulation channel.
327          */
328         if (!(id & HPET_ID_NUMBER))
329                 goto out_nohpet;
330 #endif
331
332         /* Start the counter */
333         hpet_start_counter();
334
335         /* Verify whether hpet counter works */
336         t1 = read_hpet();
337         rdtscll(start);
338
339         /*
340          * We don't know the TSC frequency yet, but waiting for
341          * 200000 TSC cycles is safe:
342          * 4 GHz == 50us
343          * 1 GHz == 200us
344          */
345         do {
346                 rep_nop();
347                 rdtscll(now);
348         } while ((now - start) < 200000UL);
349
350         if (t1 == read_hpet()) {
351                 printk(KERN_WARNING
352                        "HPET counter not counting. HPET disabled\n");
353                 goto out_nohpet;
354         }
355
356         /* Initialize and register HPET clocksource
357          *
358          * hpet period is in femto seconds per cycle
359          * so we need to convert this to ns/cyc units
360          * aproximated by mult/2^shift
361          *
362          *  fsec/cyc * 1nsec/1000000fsec = nsec/cyc = mult/2^shift
363          *  fsec/cyc * 1ns/1000000fsec * 2^shift = mult
364          *  fsec/cyc * 2^shift * 1nsec/1000000fsec = mult
365          *  (fsec/cyc << shift)/1000000 = mult
366          *  (hpet_period << shift)/FSEC_PER_NSEC = mult
367          */
368         tmp = (u64)hpet_period << HPET_SHIFT;
369         do_div(tmp, FSEC_PER_NSEC);
370         clocksource_hpet.mult = (u32)tmp;
371
372         clocksource_register(&clocksource_hpet);
373
374         if (id & HPET_ID_LEGSUP) {
375                 hpet_enable_int();
376                 /*
377                  * Start hpet with the boot cpu mask and make it
378                  * global after the IO_APIC has been initialized.
379                  */
380                 hpet_clockevent.cpumask = cpumask_of_cpu(smp_processor_id());
381                 clockevents_register_device(&hpet_clockevent);
382                 global_clock_event = &hpet_clockevent;
383                 return 1;
384         }
385         return 0;
386
387 out_nohpet:
388         hpet_clear_mapping();
389         boot_hpet_disable = 1;
390         return 0;
391 }
392
393 /*
394  * Needs to be late, as the reserve_timer code calls kalloc !
395  *
396  * Not a problem on i386 as hpet_enable is called from late_time_init,
397  * but on x86_64 it is necessary !
398  */
399 static __init int hpet_late_init(void)
400 {
401         if (!is_hpet_capable())
402                 return -ENODEV;
403
404         hpet_reserve_platform_timers(hpet_readl(HPET_ID));
405         return 0;
406 }
407 fs_initcall(hpet_late_init);
408
409 #ifdef CONFIG_HPET_EMULATE_RTC
410
411 /* HPET in LegacyReplacement Mode eats up RTC interrupt line. When, HPET
412  * is enabled, we support RTC interrupt functionality in software.
413  * RTC has 3 kinds of interrupts:
414  * 1) Update Interrupt - generate an interrupt, every sec, when RTC clock
415  *    is updated
416  * 2) Alarm Interrupt - generate an interrupt at a specific time of day
417  * 3) Periodic Interrupt - generate periodic interrupt, with frequencies
418  *    2Hz-8192Hz (2Hz-64Hz for non-root user) (all freqs in powers of 2)
419  * (1) and (2) above are implemented using polling at a frequency of
420  * 64 Hz. The exact frequency is a tradeoff between accuracy and interrupt
421  * overhead. (DEFAULT_RTC_INT_FREQ)
422  * For (3), we use interrupts at 64Hz or user specified periodic
423  * frequency, whichever is higher.
424  */
425 #include <linux/mc146818rtc.h>
426 #include <linux/rtc.h>
427
428 #define DEFAULT_RTC_INT_FREQ    64
429 #define DEFAULT_RTC_SHIFT       6
430 #define RTC_NUM_INTS            1
431
432 static unsigned long hpet_rtc_flags;
433 static unsigned long hpet_prev_update_sec;
434 static struct rtc_time hpet_alarm_time;
435 static unsigned long hpet_pie_count;
436 static unsigned long hpet_t1_cmp;
437 static unsigned long hpet_default_delta;
438 static unsigned long hpet_pie_delta;
439 static unsigned long hpet_pie_limit;
440
441 /*
442  * Timer 1 for RTC emulation. We use one shot mode, as periodic mode
443  * is not supported by all HPET implementations for timer 1.
444  *
445  * hpet_rtc_timer_init() is called when the rtc is initialized.
446  */
447 int hpet_rtc_timer_init(void)
448 {
449         unsigned long cfg, cnt, delta, flags;
450
451         if (!is_hpet_enabled())
452                 return 0;
453
454         if (!hpet_default_delta) {
455                 uint64_t clc;
456
457                 clc = (uint64_t) hpet_clockevent.mult * NSEC_PER_SEC;
458                 clc >>= hpet_clockevent.shift + DEFAULT_RTC_SHIFT;
459                 hpet_default_delta = (unsigned long) clc;
460         }
461
462         if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit)
463                 delta = hpet_default_delta;
464         else
465                 delta = hpet_pie_delta;
466
467         local_irq_save(flags);
468
469         cnt = delta + hpet_readl(HPET_COUNTER);
470         hpet_writel(cnt, HPET_T1_CMP);
471         hpet_t1_cmp = cnt;
472
473         cfg = hpet_readl(HPET_T1_CFG);
474         cfg &= ~HPET_TN_PERIODIC;
475         cfg |= HPET_TN_ENABLE | HPET_TN_32BIT;
476         hpet_writel(cfg, HPET_T1_CFG);
477
478         local_irq_restore(flags);
479
480         return 1;
481 }
482
483 /*
484  * The functions below are called from rtc driver.
485  * Return 0 if HPET is not being used.
486  * Otherwise do the necessary changes and return 1.
487  */
488 int hpet_mask_rtc_irq_bit(unsigned long bit_mask)
489 {
490         if (!is_hpet_enabled())
491                 return 0;
492
493         hpet_rtc_flags &= ~bit_mask;
494         return 1;
495 }
496
497 int hpet_set_rtc_irq_bit(unsigned long bit_mask)
498 {
499         unsigned long oldbits = hpet_rtc_flags;
500
501         if (!is_hpet_enabled())
502                 return 0;
503
504         hpet_rtc_flags |= bit_mask;
505
506         if (!oldbits)
507                 hpet_rtc_timer_init();
508
509         return 1;
510 }
511
512 int hpet_set_alarm_time(unsigned char hrs, unsigned char min,
513                         unsigned char sec)
514 {
515         if (!is_hpet_enabled())
516                 return 0;
517
518         hpet_alarm_time.tm_hour = hrs;
519         hpet_alarm_time.tm_min = min;
520         hpet_alarm_time.tm_sec = sec;
521
522         return 1;
523 }
524
525 int hpet_set_periodic_freq(unsigned long freq)
526 {
527         uint64_t clc;
528
529         if (!is_hpet_enabled())
530                 return 0;
531
532         if (freq <= DEFAULT_RTC_INT_FREQ)
533                 hpet_pie_limit = DEFAULT_RTC_INT_FREQ / freq;
534         else {
535                 clc = (uint64_t) hpet_clockevent.mult * NSEC_PER_SEC;
536                 do_div(clc, freq);
537                 clc >>= hpet_clockevent.shift;
538                 hpet_pie_delta = (unsigned long) clc;
539         }
540         return 1;
541 }
542
543 int hpet_rtc_dropped_irq(void)
544 {
545         return is_hpet_enabled();
546 }
547
548 static void hpet_rtc_timer_reinit(void)
549 {
550         unsigned long cfg, delta;
551         int lost_ints = -1;
552
553         if (unlikely(!hpet_rtc_flags)) {
554                 cfg = hpet_readl(HPET_T1_CFG);
555                 cfg &= ~HPET_TN_ENABLE;
556                 hpet_writel(cfg, HPET_T1_CFG);
557                 return;
558         }
559
560         if (!(hpet_rtc_flags & RTC_PIE) || hpet_pie_limit)
561                 delta = hpet_default_delta;
562         else
563                 delta = hpet_pie_delta;
564
565         /*
566          * Increment the comparator value until we are ahead of the
567          * current count.
568          */
569         do {
570                 hpet_t1_cmp += delta;
571                 hpet_writel(hpet_t1_cmp, HPET_T1_CMP);
572                 lost_ints++;
573         } while ((long)(hpet_readl(HPET_COUNTER) - hpet_t1_cmp) > 0);
574
575         if (lost_ints) {
576                 if (hpet_rtc_flags & RTC_PIE)
577                         hpet_pie_count += lost_ints;
578                 if (printk_ratelimit())
579                         printk(KERN_WARNING "rtc: lost %d interrupts\n",
580                                 lost_ints);
581         }
582 }
583
584 irqreturn_t hpet_rtc_interrupt(int irq, void *dev_id)
585 {
586         struct rtc_time curr_time;
587         unsigned long rtc_int_flag = 0;
588
589         hpet_rtc_timer_reinit();
590
591         if (hpet_rtc_flags & (RTC_UIE | RTC_AIE))
592                 rtc_get_rtc_time(&curr_time);
593
594         if (hpet_rtc_flags & RTC_UIE &&
595             curr_time.tm_sec != hpet_prev_update_sec) {
596                 rtc_int_flag = RTC_UF;
597                 hpet_prev_update_sec = curr_time.tm_sec;
598         }
599
600         if (hpet_rtc_flags & RTC_PIE &&
601             ++hpet_pie_count >= hpet_pie_limit) {
602                 rtc_int_flag |= RTC_PF;
603                 hpet_pie_count = 0;
604         }
605
606         if (hpet_rtc_flags & RTC_PIE &&
607             (curr_time.tm_sec == hpet_alarm_time.tm_sec) &&
608             (curr_time.tm_min == hpet_alarm_time.tm_min) &&
609             (curr_time.tm_hour == hpet_alarm_time.tm_hour))
610                         rtc_int_flag |= RTC_AF;
611
612         if (rtc_int_flag) {
613                 rtc_int_flag |= (RTC_IRQF | (RTC_NUM_INTS << 8));
614                 rtc_interrupt(rtc_int_flag, dev_id);
615         }
616         return IRQ_HANDLED;
617 }
618 #endif