hpet.c revision 9f75e9b74a45d7d3c343c8979f49d5e6b92bbce3
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 */ 25unsigned long hpet_address; 26static 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 32static inline unsigned long hpet_readl(unsigned long a) 33{ 34 return readl(hpet_virt_address + a); 35} 36 37static 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 46static 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 53static inline void hpet_clear_mapping(void) 54{ 55 hpet_virt_address = NULL; 56} 57 58#else 59 60static inline void hpet_set_mapping(void) 61{ 62 hpet_virt_address = ioremap_nocache(hpet_address, HPET_MMAP_SIZE); 63} 64 65static 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 */ 75static int boot_hpet_disable; 76 77static 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 87static int __init disable_hpet(char *str) 88{ 89 boot_hpet_disable = 1; 90 return 1; 91} 92__setup("nohpet", disable_hpet); 93 94static inline int is_hpet_capable(void) 95{ 96 return (!boot_hpet_disable && hpet_address); 97} 98 99/* 100 * HPET timer interrupt enable / disable 101 */ 102static int hpet_legacy_int_enabled; 103 104/** 105 * is_hpet_enabled - check whether the hpet timer interrupt is enabled 106 */ 107int 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 117static 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 148static void hpet_reserve_platform_timers(unsigned long id) { } 149#endif 150 151/* 152 * Common hpet info 153 */ 154static unsigned long hpet_period; 155 156static void hpet_set_mode(enum clock_event_mode mode, 157 struct clock_event_device *evt); 158static int hpet_next_event(unsigned long delta, 159 struct clock_event_device *evt); 160 161/* 162 * The hpet clock event device 163 */ 164static 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 173static 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 185static 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 194static 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 240static 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 */ 255static cycle_t read_hpet(void) 256{ 257 return (cycle_t)hpet_readl(HPET_COUNTER); 258} 259 260#ifdef CONFIG_X86_64 261static cycle_t __vsyscall_fn vread_hpet(void) 262{ 263 return readl((const void __iomem *)fix_to_virt(VSYSCALL_HPET) + 0xf0); 264} 265#endif 266 267static 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 */ 283int __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 387out_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 */ 399static __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} 407fs_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 432static unsigned long hpet_rtc_flags; 433static unsigned long hpet_prev_update_sec; 434static struct rtc_time hpet_alarm_time; 435static unsigned long hpet_pie_count; 436static unsigned long hpet_t1_cmp; 437static unsigned long hpet_default_delta; 438static unsigned long hpet_pie_delta; 439static 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 */ 447int 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 */ 488int 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 497int 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 512int 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 525int 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 543int hpet_rtc_dropped_irq(void) 544{ 545 return is_hpet_enabled(); 546} 547 548static 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 584irqreturn_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 619