11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds * linux/arch/alpha/kernel/time.c 31da177e4SLinus Torvalds * 41da177e4SLinus Torvalds * Copyright (C) 1991, 1992, 1995, 1999, 2000 Linus Torvalds 51da177e4SLinus Torvalds * 61da177e4SLinus Torvalds * This file contains the PC-specific time handling details: 71da177e4SLinus Torvalds * reading the RTC at bootup, etc.. 81da177e4SLinus Torvalds * 1994-07-02 Alan Modra 91da177e4SLinus Torvalds * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime 101da177e4SLinus Torvalds * 1995-03-26 Markus Kuhn 111da177e4SLinus Torvalds * fixed 500 ms bug at call to set_rtc_mmss, fixed DS12887 121da177e4SLinus Torvalds * precision CMOS clock update 131da177e4SLinus Torvalds * 1997-09-10 Updated NTP code according to technical memorandum Jan '96 141da177e4SLinus Torvalds * "A Kernel Model for Precision Timekeeping" by Dave Mills 151da177e4SLinus Torvalds * 1997-01-09 Adrian Sun 161da177e4SLinus Torvalds * use interval timer if CONFIG_RTC=y 171da177e4SLinus Torvalds * 1997-10-29 John Bowman (bowman@math.ualberta.ca) 181da177e4SLinus Torvalds * fixed tick loss calculation in timer_interrupt 191da177e4SLinus Torvalds * (round system clock to nearest tick instead of truncating) 201da177e4SLinus Torvalds * fixed algorithm in time_init for getting time from CMOS clock 211da177e4SLinus Torvalds * 1999-04-16 Thorsten Kranzkowski (dl8bcu@gmx.net) 221da177e4SLinus Torvalds * fixed algorithm in do_gettimeofday() for calculating the precise time 231da177e4SLinus Torvalds * from processor cycle counter (now taking lost_ticks into account) 241da177e4SLinus Torvalds * 2000-08-13 Jan-Benedict Glaw <jbglaw@lug-owl.de> 251da177e4SLinus Torvalds * Fixed time_init to be aware of epoches != 1900. This prevents 261da177e4SLinus Torvalds * booting up in 2048 for me;) Code is stolen from rtc.c. 271da177e4SLinus Torvalds * 2003-06-03 R. Scott Bailey <scott.bailey@eds.com> 281da177e4SLinus Torvalds * Tighten sanity in time_init from 1% (10,000 PPM) to 250 PPM 291da177e4SLinus Torvalds */ 301da177e4SLinus Torvalds #include <linux/errno.h> 311da177e4SLinus Torvalds #include <linux/module.h> 321da177e4SLinus Torvalds #include <linux/sched.h> 331da177e4SLinus Torvalds #include <linux/kernel.h> 341da177e4SLinus Torvalds #include <linux/param.h> 351da177e4SLinus Torvalds #include <linux/string.h> 361da177e4SLinus Torvalds #include <linux/mm.h> 371da177e4SLinus Torvalds #include <linux/delay.h> 381da177e4SLinus Torvalds #include <linux/ioport.h> 391da177e4SLinus Torvalds #include <linux/irq.h> 401da177e4SLinus Torvalds #include <linux/interrupt.h> 411da177e4SLinus Torvalds #include <linux/init.h> 421da177e4SLinus Torvalds #include <linux/bcd.h> 431da177e4SLinus Torvalds #include <linux/profile.h> 44e360adbeSPeter Zijlstra #include <linux/irq_work.h> 451da177e4SLinus Torvalds 461da177e4SLinus Torvalds #include <asm/uaccess.h> 471da177e4SLinus Torvalds #include <asm/io.h> 481da177e4SLinus Torvalds #include <asm/hwrpb.h> 495f7dc5d7SIvan Kokshaysky #include <asm/rtc.h> 501da177e4SLinus Torvalds 511da177e4SLinus Torvalds #include <linux/mc146818rtc.h> 521da177e4SLinus Torvalds #include <linux/time.h> 531da177e4SLinus Torvalds #include <linux/timex.h> 549ce34c8fSJohn Stultz #include <linux/clocksource.h> 551da177e4SLinus Torvalds 561da177e4SLinus Torvalds #include "proto.h" 571da177e4SLinus Torvalds #include "irq_impl.h" 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds static int set_rtc_mmss(unsigned long); 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds DEFINE_SPINLOCK(rtc_lock); 62cff52dafSAl Viro EXPORT_SYMBOL(rtc_lock); 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds #define TICK_SIZE (tick_nsec / 1000) 651da177e4SLinus Torvalds 661da177e4SLinus Torvalds /* 671da177e4SLinus Torvalds * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting 681da177e4SLinus Torvalds * by 48 gives us 16 bits for HZ while keeping the accuracy good even 691da177e4SLinus Torvalds * for large CPU clock rates. 701da177e4SLinus Torvalds */ 711da177e4SLinus Torvalds #define FIX_SHIFT 48 721da177e4SLinus Torvalds 731da177e4SLinus Torvalds /* lump static variables together for more efficient access: */ 741da177e4SLinus Torvalds static struct { 751da177e4SLinus Torvalds /* cycle counter last time it got invoked */ 761da177e4SLinus Torvalds __u32 last_time; 771da177e4SLinus Torvalds /* ticks/cycle * 2^48 */ 781da177e4SLinus Torvalds unsigned long scaled_ticks_per_cycle; 791da177e4SLinus Torvalds /* partial unused tick */ 801da177e4SLinus Torvalds unsigned long partial_tick; 811da177e4SLinus Torvalds } state; 821da177e4SLinus Torvalds 831da177e4SLinus Torvalds unsigned long est_cycle_freq; 841da177e4SLinus Torvalds 85e360adbeSPeter Zijlstra #ifdef CONFIG_IRQ_WORK 86979f8671SMichael Cree 87e360adbeSPeter Zijlstra DEFINE_PER_CPU(u8, irq_work_pending); 88979f8671SMichael Cree 89e360adbeSPeter Zijlstra #define set_irq_work_pending_flag() __get_cpu_var(irq_work_pending) = 1 90e360adbeSPeter Zijlstra #define test_irq_work_pending() __get_cpu_var(irq_work_pending) 91e360adbeSPeter Zijlstra #define clear_irq_work_pending() __get_cpu_var(irq_work_pending) = 0 92979f8671SMichael Cree 930f933625SPeter Zijlstra void arch_irq_work_raise(void) 94979f8671SMichael Cree { 95e360adbeSPeter Zijlstra set_irq_work_pending_flag(); 96979f8671SMichael Cree } 97979f8671SMichael Cree 98e360adbeSPeter Zijlstra #else /* CONFIG_IRQ_WORK */ 99979f8671SMichael Cree 100e360adbeSPeter Zijlstra #define test_irq_work_pending() 0 101e360adbeSPeter Zijlstra #define clear_irq_work_pending() 102979f8671SMichael Cree 103e360adbeSPeter Zijlstra #endif /* CONFIG_IRQ_WORK */ 104979f8671SMichael Cree 1051da177e4SLinus Torvalds 1061da177e4SLinus Torvalds static inline __u32 rpcc(void) 1071da177e4SLinus Torvalds { 10891531b05SRichard Henderson return __builtin_alpha_rpcc(); 1091da177e4SLinus Torvalds } 1101da177e4SLinus Torvalds 1111e871be1SJohn Stultz int update_persistent_clock(struct timespec now) 1121e871be1SJohn Stultz { 1131e871be1SJohn Stultz return set_rtc_mmss(now.tv_sec); 1141e871be1SJohn Stultz } 1151e871be1SJohn Stultz 1161e871be1SJohn Stultz void read_persistent_clock(struct timespec *ts) 1171e871be1SJohn Stultz { 1181e871be1SJohn Stultz unsigned int year, mon, day, hour, min, sec, epoch; 1191e871be1SJohn Stultz 1201e871be1SJohn Stultz sec = CMOS_READ(RTC_SECONDS); 1211e871be1SJohn Stultz min = CMOS_READ(RTC_MINUTES); 1221e871be1SJohn Stultz hour = CMOS_READ(RTC_HOURS); 1231e871be1SJohn Stultz day = CMOS_READ(RTC_DAY_OF_MONTH); 1241e871be1SJohn Stultz mon = CMOS_READ(RTC_MONTH); 1251e871be1SJohn Stultz year = CMOS_READ(RTC_YEAR); 1261e871be1SJohn Stultz 1271e871be1SJohn Stultz if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 1281e871be1SJohn Stultz sec = bcd2bin(sec); 1291e871be1SJohn Stultz min = bcd2bin(min); 1301e871be1SJohn Stultz hour = bcd2bin(hour); 1311e871be1SJohn Stultz day = bcd2bin(day); 1321e871be1SJohn Stultz mon = bcd2bin(mon); 1331e871be1SJohn Stultz year = bcd2bin(year); 1341e871be1SJohn Stultz } 1351e871be1SJohn Stultz 1361e871be1SJohn Stultz /* PC-like is standard; used for year >= 70 */ 1371e871be1SJohn Stultz epoch = 1900; 1381e871be1SJohn Stultz if (year < 20) 1391e871be1SJohn Stultz epoch = 2000; 1401e871be1SJohn Stultz else if (year >= 20 && year < 48) 1411e871be1SJohn Stultz /* NT epoch */ 1421e871be1SJohn Stultz epoch = 1980; 1431e871be1SJohn Stultz else if (year >= 48 && year < 70) 1441e871be1SJohn Stultz /* Digital UNIX epoch */ 1451e871be1SJohn Stultz epoch = 1952; 1461e871be1SJohn Stultz 1471e871be1SJohn Stultz printk(KERN_INFO "Using epoch = %d\n", epoch); 1481e871be1SJohn Stultz 1491e871be1SJohn Stultz if ((year += epoch) < 1970) 1501e871be1SJohn Stultz year += 100; 1511e871be1SJohn Stultz 1521e871be1SJohn Stultz ts->tv_sec = mktime(year, mon, day, hour, min, sec); 153a78eda5cSRichard Henderson ts->tv_nsec = 0; 1541e871be1SJohn Stultz } 1551e871be1SJohn Stultz 1561e871be1SJohn Stultz 1571e871be1SJohn Stultz 1581da177e4SLinus Torvalds /* 1591da177e4SLinus Torvalds * timer_interrupt() needs to keep up the real-time clock, 1601340f3e0STorben Hohn * as well as call the "xtime_update()" routine every clocktick 1611da177e4SLinus Torvalds */ 1628774cb81SAl Viro irqreturn_t timer_interrupt(int irq, void *dev) 1631da177e4SLinus Torvalds { 1641da177e4SLinus Torvalds unsigned long delta; 1651da177e4SLinus Torvalds __u32 now; 1661da177e4SLinus Torvalds long nticks; 1671da177e4SLinus Torvalds 1681da177e4SLinus Torvalds #ifndef CONFIG_SMP 1691da177e4SLinus Torvalds /* Not SMP, do kernel PC profiling here. */ 1708774cb81SAl Viro profile_tick(CPU_PROFILING); 1711da177e4SLinus Torvalds #endif 1721da177e4SLinus Torvalds 1731da177e4SLinus Torvalds /* 1741da177e4SLinus Torvalds * Calculate how many ticks have passed since the last update, 1751da177e4SLinus Torvalds * including any previous partial leftover. Save any resulting 1761da177e4SLinus Torvalds * fraction for the next pass. 1771da177e4SLinus Torvalds */ 1781da177e4SLinus Torvalds now = rpcc(); 1791da177e4SLinus Torvalds delta = now - state.last_time; 1801da177e4SLinus Torvalds state.last_time = now; 1811da177e4SLinus Torvalds delta = delta * state.scaled_ticks_per_cycle + state.partial_tick; 1821da177e4SLinus Torvalds state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1); 1831da177e4SLinus Torvalds nticks = delta >> FIX_SHIFT; 1841da177e4SLinus Torvalds 185aa02cd2dSPeter Zijlstra if (nticks) 1861340f3e0STorben Hohn xtime_update(nticks); 187aa02cd2dSPeter Zijlstra 188e360adbeSPeter Zijlstra if (test_irq_work_pending()) { 189e360adbeSPeter Zijlstra clear_irq_work_pending(); 190e360adbeSPeter Zijlstra irq_work_run(); 191979f8671SMichael Cree } 192979f8671SMichael Cree 193bdc8b891SMichael Cree #ifndef CONFIG_SMP 194bdc8b891SMichael Cree while (nticks--) 195bdc8b891SMichael Cree update_process_times(user_mode(get_irq_regs())); 196bdc8b891SMichael Cree #endif 197bdc8b891SMichael Cree 1981da177e4SLinus Torvalds return IRQ_HANDLED; 1991da177e4SLinus Torvalds } 2001da177e4SLinus Torvalds 201ebaf4fc1SSam Ravnborg void __init 2021da177e4SLinus Torvalds common_init_rtc(void) 2031da177e4SLinus Torvalds { 2041da177e4SLinus Torvalds unsigned char x; 2051da177e4SLinus Torvalds 2061da177e4SLinus Torvalds /* Reset periodic interrupt frequency. */ 2071da177e4SLinus Torvalds x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; 2081da177e4SLinus Torvalds /* Test includes known working values on various platforms 2091da177e4SLinus Torvalds where 0x26 is wrong; we refuse to change those. */ 2101da177e4SLinus Torvalds if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) { 2111da177e4SLinus Torvalds printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x); 2121da177e4SLinus Torvalds CMOS_WRITE(0x26, RTC_FREQ_SELECT); 2131da177e4SLinus Torvalds } 2141da177e4SLinus Torvalds 2151da177e4SLinus Torvalds /* Turn on periodic interrupts. */ 2161da177e4SLinus Torvalds x = CMOS_READ(RTC_CONTROL); 2171da177e4SLinus Torvalds if (!(x & RTC_PIE)) { 2181da177e4SLinus Torvalds printk("Turning on RTC interrupts.\n"); 2191da177e4SLinus Torvalds x |= RTC_PIE; 2201da177e4SLinus Torvalds x &= ~(RTC_AIE | RTC_UIE); 2211da177e4SLinus Torvalds CMOS_WRITE(x, RTC_CONTROL); 2221da177e4SLinus Torvalds } 2231da177e4SLinus Torvalds (void) CMOS_READ(RTC_INTR_FLAGS); 2241da177e4SLinus Torvalds 2251da177e4SLinus Torvalds outb(0x36, 0x43); /* pit counter 0: system timer */ 2261da177e4SLinus Torvalds outb(0x00, 0x40); 2271da177e4SLinus Torvalds outb(0x00, 0x40); 2281da177e4SLinus Torvalds 2291da177e4SLinus Torvalds outb(0xb6, 0x43); /* pit counter 2: speaker */ 2301da177e4SLinus Torvalds outb(0x31, 0x42); 2311da177e4SLinus Torvalds outb(0x13, 0x42); 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds init_rtc_irq(); 2341da177e4SLinus Torvalds } 2351da177e4SLinus Torvalds 2365f7dc5d7SIvan Kokshaysky unsigned int common_get_rtc_time(struct rtc_time *time) 2375f7dc5d7SIvan Kokshaysky { 2385f7dc5d7SIvan Kokshaysky return __get_rtc_time(time); 2395f7dc5d7SIvan Kokshaysky } 2405f7dc5d7SIvan Kokshaysky 2415f7dc5d7SIvan Kokshaysky int common_set_rtc_time(struct rtc_time *time) 2425f7dc5d7SIvan Kokshaysky { 2435f7dc5d7SIvan Kokshaysky return __set_rtc_time(time); 2445f7dc5d7SIvan Kokshaysky } 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds /* Validate a computed cycle counter result against the known bounds for 2471da177e4SLinus Torvalds the given processor core. There's too much brokenness in the way of 2481da177e4SLinus Torvalds timing hardware for any one method to work everywhere. :-( 2491da177e4SLinus Torvalds 2501da177e4SLinus Torvalds Return 0 if the result cannot be trusted, otherwise return the argument. */ 2511da177e4SLinus Torvalds 2521da177e4SLinus Torvalds static unsigned long __init 2531da177e4SLinus Torvalds validate_cc_value(unsigned long cc) 2541da177e4SLinus Torvalds { 2551da177e4SLinus Torvalds static struct bounds { 2561da177e4SLinus Torvalds unsigned int min, max; 2571da177e4SLinus Torvalds } cpu_hz[] __initdata = { 2581da177e4SLinus Torvalds [EV3_CPU] = { 50000000, 200000000 }, /* guess */ 2591da177e4SLinus Torvalds [EV4_CPU] = { 100000000, 300000000 }, 2601da177e4SLinus Torvalds [LCA4_CPU] = { 100000000, 300000000 }, /* guess */ 2611da177e4SLinus Torvalds [EV45_CPU] = { 200000000, 300000000 }, 2621da177e4SLinus Torvalds [EV5_CPU] = { 250000000, 433000000 }, 2631da177e4SLinus Torvalds [EV56_CPU] = { 333000000, 667000000 }, 2641da177e4SLinus Torvalds [PCA56_CPU] = { 400000000, 600000000 }, /* guess */ 2651da177e4SLinus Torvalds [PCA57_CPU] = { 500000000, 600000000 }, /* guess */ 2661da177e4SLinus Torvalds [EV6_CPU] = { 466000000, 600000000 }, 2671da177e4SLinus Torvalds [EV67_CPU] = { 600000000, 750000000 }, 2681da177e4SLinus Torvalds [EV68AL_CPU] = { 750000000, 940000000 }, 2691da177e4SLinus Torvalds [EV68CB_CPU] = { 1000000000, 1333333333 }, 2701da177e4SLinus Torvalds /* None of the following are shipping as of 2001-11-01. */ 2711da177e4SLinus Torvalds [EV68CX_CPU] = { 1000000000, 1700000000 }, /* guess */ 2721da177e4SLinus Torvalds [EV69_CPU] = { 1000000000, 1700000000 }, /* guess */ 2731da177e4SLinus Torvalds [EV7_CPU] = { 800000000, 1400000000 }, /* guess */ 2741da177e4SLinus Torvalds [EV79_CPU] = { 1000000000, 2000000000 }, /* guess */ 2751da177e4SLinus Torvalds }; 2761da177e4SLinus Torvalds 2771da177e4SLinus Torvalds /* Allow for some drift in the crystal. 10MHz is more than enough. */ 2781da177e4SLinus Torvalds const unsigned int deviation = 10000000; 2791da177e4SLinus Torvalds 2801da177e4SLinus Torvalds struct percpu_struct *cpu; 2811da177e4SLinus Torvalds unsigned int index; 2821da177e4SLinus Torvalds 2831da177e4SLinus Torvalds cpu = (struct percpu_struct *)((char*)hwrpb + hwrpb->processor_offset); 2841da177e4SLinus Torvalds index = cpu->type & 0xffffffff; 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds /* If index out of bounds, no way to validate. */ 28725c8716cSTobias Klauser if (index >= ARRAY_SIZE(cpu_hz)) 2881da177e4SLinus Torvalds return cc; 2891da177e4SLinus Torvalds 2901da177e4SLinus Torvalds /* If index contains no data, no way to validate. */ 2911da177e4SLinus Torvalds if (cpu_hz[index].max == 0) 2921da177e4SLinus Torvalds return cc; 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds if (cc < cpu_hz[index].min - deviation 2951da177e4SLinus Torvalds || cc > cpu_hz[index].max + deviation) 2961da177e4SLinus Torvalds return 0; 2971da177e4SLinus Torvalds 2981da177e4SLinus Torvalds return cc; 2991da177e4SLinus Torvalds } 3001da177e4SLinus Torvalds 3011da177e4SLinus Torvalds 3021da177e4SLinus Torvalds /* 3031da177e4SLinus Torvalds * Calibrate CPU clock using legacy 8254 timer/counter. Stolen from 3041da177e4SLinus Torvalds * arch/i386/time.c. 3051da177e4SLinus Torvalds */ 3061da177e4SLinus Torvalds 3071da177e4SLinus Torvalds #define CALIBRATE_LATCH 0xffff 3081da177e4SLinus Torvalds #define TIMEOUT_COUNT 0x100000 3091da177e4SLinus Torvalds 3101da177e4SLinus Torvalds static unsigned long __init 3111da177e4SLinus Torvalds calibrate_cc_with_pit(void) 3121da177e4SLinus Torvalds { 3131da177e4SLinus Torvalds int cc, count = 0; 3141da177e4SLinus Torvalds 3151da177e4SLinus Torvalds /* Set the Gate high, disable speaker */ 3161da177e4SLinus Torvalds outb((inb(0x61) & ~0x02) | 0x01, 0x61); 3171da177e4SLinus Torvalds 3181da177e4SLinus Torvalds /* 3191da177e4SLinus Torvalds * Now let's take care of CTC channel 2 3201da177e4SLinus Torvalds * 3211da177e4SLinus Torvalds * Set the Gate high, program CTC channel 2 for mode 0, 3221da177e4SLinus Torvalds * (interrupt on terminal count mode), binary count, 3231da177e4SLinus Torvalds * load 5 * LATCH count, (LSB and MSB) to begin countdown. 3241da177e4SLinus Torvalds */ 3251da177e4SLinus Torvalds outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */ 3261da177e4SLinus Torvalds outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */ 3271da177e4SLinus Torvalds outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */ 3281da177e4SLinus Torvalds 3291da177e4SLinus Torvalds cc = rpcc(); 3301da177e4SLinus Torvalds do { 3311da177e4SLinus Torvalds count++; 3321da177e4SLinus Torvalds } while ((inb(0x61) & 0x20) == 0 && count < TIMEOUT_COUNT); 3331da177e4SLinus Torvalds cc = rpcc() - cc; 3341da177e4SLinus Torvalds 3351da177e4SLinus Torvalds /* Error: ECTCNEVERSET or ECPUTOOFAST. */ 3361da177e4SLinus Torvalds if (count <= 1 || count == TIMEOUT_COUNT) 3371da177e4SLinus Torvalds return 0; 3381da177e4SLinus Torvalds 3391da177e4SLinus Torvalds return ((long)cc * PIT_TICK_RATE) / (CALIBRATE_LATCH + 1); 3401da177e4SLinus Torvalds } 3411da177e4SLinus Torvalds 3421da177e4SLinus Torvalds /* The Linux interpretation of the CMOS clock register contents: 3431da177e4SLinus Torvalds When the Update-In-Progress (UIP) flag goes from 1 to 0, the 3441da177e4SLinus Torvalds RTC registers show the second which has precisely just started. 3451da177e4SLinus Torvalds Let's hope other operating systems interpret the RTC the same way. */ 3461da177e4SLinus Torvalds 3471da177e4SLinus Torvalds static unsigned long __init 3481da177e4SLinus Torvalds rpcc_after_update_in_progress(void) 3491da177e4SLinus Torvalds { 3501da177e4SLinus Torvalds do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)); 3511da177e4SLinus Torvalds do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); 3521da177e4SLinus Torvalds 3531da177e4SLinus Torvalds return rpcc(); 3541da177e4SLinus Torvalds } 3551da177e4SLinus Torvalds 3569ce34c8fSJohn Stultz #ifndef CONFIG_SMP 3579ce34c8fSJohn Stultz /* Until and unless we figure out how to get cpu cycle counters 3589ce34c8fSJohn Stultz in sync and keep them there, we can't use the rpcc. */ 3599ce34c8fSJohn Stultz static cycle_t read_rpcc(struct clocksource *cs) 3609ce34c8fSJohn Stultz { 3619ce34c8fSJohn Stultz cycle_t ret = (cycle_t)rpcc(); 3629ce34c8fSJohn Stultz return ret; 3639ce34c8fSJohn Stultz } 3649ce34c8fSJohn Stultz 3659ce34c8fSJohn Stultz static struct clocksource clocksource_rpcc = { 3669ce34c8fSJohn Stultz .name = "rpcc", 3679ce34c8fSJohn Stultz .rating = 300, 3689ce34c8fSJohn Stultz .read = read_rpcc, 3699ce34c8fSJohn Stultz .mask = CLOCKSOURCE_MASK(32), 3709ce34c8fSJohn Stultz .flags = CLOCK_SOURCE_IS_CONTINUOUS 3719ce34c8fSJohn Stultz }; 3729ce34c8fSJohn Stultz 3739ce34c8fSJohn Stultz static inline void register_rpcc_clocksource(long cycle_freq) 3749ce34c8fSJohn Stultz { 375f550806aSJohn Stultz clocksource_register_hz(&clocksource_rpcc, cycle_freq); 3769ce34c8fSJohn Stultz } 3779ce34c8fSJohn Stultz #else /* !CONFIG_SMP */ 3789ce34c8fSJohn Stultz static inline void register_rpcc_clocksource(long cycle_freq) 3799ce34c8fSJohn Stultz { 3809ce34c8fSJohn Stultz } 3819ce34c8fSJohn Stultz #endif /* !CONFIG_SMP */ 3829ce34c8fSJohn Stultz 3831da177e4SLinus Torvalds void __init 3841da177e4SLinus Torvalds time_init(void) 3851da177e4SLinus Torvalds { 3861e871be1SJohn Stultz unsigned int cc1, cc2; 3871da177e4SLinus Torvalds unsigned long cycle_freq, tolerance; 3881da177e4SLinus Torvalds long diff; 3891da177e4SLinus Torvalds 3901da177e4SLinus Torvalds /* Calibrate CPU clock -- attempt #1. */ 3911da177e4SLinus Torvalds if (!est_cycle_freq) 3921da177e4SLinus Torvalds est_cycle_freq = validate_cc_value(calibrate_cc_with_pit()); 3931da177e4SLinus Torvalds 3944c2e6f6aSMatt Mackall cc1 = rpcc(); 3951da177e4SLinus Torvalds 3961da177e4SLinus Torvalds /* Calibrate CPU clock -- attempt #2. */ 3971da177e4SLinus Torvalds if (!est_cycle_freq) { 3984c2e6f6aSMatt Mackall cc1 = rpcc_after_update_in_progress(); 3991da177e4SLinus Torvalds cc2 = rpcc_after_update_in_progress(); 4001da177e4SLinus Torvalds est_cycle_freq = validate_cc_value(cc2 - cc1); 4011da177e4SLinus Torvalds cc1 = cc2; 4021da177e4SLinus Torvalds } 4031da177e4SLinus Torvalds 4041da177e4SLinus Torvalds cycle_freq = hwrpb->cycle_freq; 4051da177e4SLinus Torvalds if (est_cycle_freq) { 4061da177e4SLinus Torvalds /* If the given value is within 250 PPM of what we calculated, 4071da177e4SLinus Torvalds accept it. Otherwise, use what we found. */ 4081da177e4SLinus Torvalds tolerance = cycle_freq / 4000; 4091da177e4SLinus Torvalds diff = cycle_freq - est_cycle_freq; 4101da177e4SLinus Torvalds if (diff < 0) 4111da177e4SLinus Torvalds diff = -diff; 4121da177e4SLinus Torvalds if ((unsigned long)diff > tolerance) { 4131da177e4SLinus Torvalds cycle_freq = est_cycle_freq; 4141da177e4SLinus Torvalds printk("HWRPB cycle frequency bogus. " 4151da177e4SLinus Torvalds "Estimated %lu Hz\n", cycle_freq); 4161da177e4SLinus Torvalds } else { 4171da177e4SLinus Torvalds est_cycle_freq = 0; 4181da177e4SLinus Torvalds } 4191da177e4SLinus Torvalds } else if (! validate_cc_value (cycle_freq)) { 4201da177e4SLinus Torvalds printk("HWRPB cycle frequency bogus, " 4211da177e4SLinus Torvalds "and unable to estimate a proper value!\n"); 4221da177e4SLinus Torvalds } 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds /* From John Bowman <bowman@math.ualberta.ca>: allow the values 4251da177e4SLinus Torvalds to settle, as the Update-In-Progress bit going low isn't good 4261da177e4SLinus Torvalds enough on some hardware. 2ms is our guess; we haven't found 4271da177e4SLinus Torvalds bogomips yet, but this is close on a 500Mhz box. */ 4281da177e4SLinus Torvalds __delay(1000000); 4291da177e4SLinus Torvalds 4301da177e4SLinus Torvalds 4311da177e4SLinus Torvalds if (HZ > (1<<16)) { 4321da177e4SLinus Torvalds extern void __you_loose (void); 4331da177e4SLinus Torvalds __you_loose(); 4341da177e4SLinus Torvalds } 4351da177e4SLinus Torvalds 4369ce34c8fSJohn Stultz register_rpcc_clocksource(cycle_freq); 4379ce34c8fSJohn Stultz 4381da177e4SLinus Torvalds state.last_time = cc1; 4391da177e4SLinus Torvalds state.scaled_ticks_per_cycle 4401da177e4SLinus Torvalds = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; 4411da177e4SLinus Torvalds state.partial_tick = 0L; 4421da177e4SLinus Torvalds 4431da177e4SLinus Torvalds /* Startup the timer source. */ 4441da177e4SLinus Torvalds alpha_mv.init_rtc(); 4451da177e4SLinus Torvalds } 4461da177e4SLinus Torvalds 4471da177e4SLinus Torvalds /* 4481da177e4SLinus Torvalds * In order to set the CMOS clock precisely, set_rtc_mmss has to be 4491da177e4SLinus Torvalds * called 500 ms after the second nowtime has started, because when 4501da177e4SLinus Torvalds * nowtime is written into the registers of the CMOS clock, it will 4511da177e4SLinus Torvalds * jump to the next second precisely 500 ms later. Check the Motorola 4521da177e4SLinus Torvalds * MC146818A or Dallas DS12887 data sheet for details. 4531da177e4SLinus Torvalds * 4541da177e4SLinus Torvalds * BUG: This routine does not handle hour overflow properly; it just 4551da177e4SLinus Torvalds * sets the minutes. Usually you won't notice until after reboot! 4561da177e4SLinus Torvalds */ 4571da177e4SLinus Torvalds 4581da177e4SLinus Torvalds 4591da177e4SLinus Torvalds static int 4601da177e4SLinus Torvalds set_rtc_mmss(unsigned long nowtime) 4611da177e4SLinus Torvalds { 4621da177e4SLinus Torvalds int retval = 0; 4631da177e4SLinus Torvalds int real_seconds, real_minutes, cmos_minutes; 4641da177e4SLinus Torvalds unsigned char save_control, save_freq_select; 4651da177e4SLinus Torvalds 4661da177e4SLinus Torvalds /* irq are locally disabled here */ 4671da177e4SLinus Torvalds spin_lock(&rtc_lock); 4681da177e4SLinus Torvalds /* Tell the clock it's being set */ 4691da177e4SLinus Torvalds save_control = CMOS_READ(RTC_CONTROL); 4701da177e4SLinus Torvalds CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds /* Stop and reset prescaler */ 4731da177e4SLinus Torvalds save_freq_select = CMOS_READ(RTC_FREQ_SELECT); 4741da177e4SLinus Torvalds CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 4751da177e4SLinus Torvalds 4761da177e4SLinus Torvalds cmos_minutes = CMOS_READ(RTC_MINUTES); 4771da177e4SLinus Torvalds if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 47818b1bd05SAdrian Bunk cmos_minutes = bcd2bin(cmos_minutes); 4791da177e4SLinus Torvalds 4801da177e4SLinus Torvalds /* 4811da177e4SLinus Torvalds * since we're only adjusting minutes and seconds, 4821da177e4SLinus Torvalds * don't interfere with hour overflow. This avoids 4831da177e4SLinus Torvalds * messing with unknown time zones but requires your 4841da177e4SLinus Torvalds * RTC not to be off by more than 15 minutes 4851da177e4SLinus Torvalds */ 4861da177e4SLinus Torvalds real_seconds = nowtime % 60; 4871da177e4SLinus Torvalds real_minutes = nowtime / 60; 4881da177e4SLinus Torvalds if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) { 4891da177e4SLinus Torvalds /* correct for half hour time zone */ 4901da177e4SLinus Torvalds real_minutes += 30; 4911da177e4SLinus Torvalds } 4921da177e4SLinus Torvalds real_minutes %= 60; 4931da177e4SLinus Torvalds 4941da177e4SLinus Torvalds if (abs(real_minutes - cmos_minutes) < 30) { 4951da177e4SLinus Torvalds if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 49618b1bd05SAdrian Bunk real_seconds = bin2bcd(real_seconds); 49718b1bd05SAdrian Bunk real_minutes = bin2bcd(real_minutes); 4981da177e4SLinus Torvalds } 4991da177e4SLinus Torvalds CMOS_WRITE(real_seconds,RTC_SECONDS); 5001da177e4SLinus Torvalds CMOS_WRITE(real_minutes,RTC_MINUTES); 5011da177e4SLinus Torvalds } else { 5023e5c1240SStephen Hemminger printk_once(KERN_NOTICE 5031da177e4SLinus Torvalds "set_rtc_mmss: can't update from %d to %d\n", 5041da177e4SLinus Torvalds cmos_minutes, real_minutes); 5051da177e4SLinus Torvalds retval = -1; 5061da177e4SLinus Torvalds } 5071da177e4SLinus Torvalds 5081da177e4SLinus Torvalds /* The following flags have to be released exactly in this order, 5091da177e4SLinus Torvalds * otherwise the DS12887 (popular MC146818A clone with integrated 5101da177e4SLinus Torvalds * battery and quartz) will not reset the oscillator and will not 5111da177e4SLinus Torvalds * update precisely 500 ms later. You won't find this mentioned in 5121da177e4SLinus Torvalds * the Dallas Semiconductor data sheets, but who believes data 5131da177e4SLinus Torvalds * sheets anyway ... -- Markus Kuhn 5141da177e4SLinus Torvalds */ 5151da177e4SLinus Torvalds CMOS_WRITE(save_control, RTC_CONTROL); 5161da177e4SLinus Torvalds CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 5171da177e4SLinus Torvalds spin_unlock(&rtc_lock); 5181da177e4SLinus Torvalds 5191da177e4SLinus Torvalds return retval; 5201da177e4SLinus Torvalds } 521