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> 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds #include <asm/uaccess.h> 461da177e4SLinus Torvalds #include <asm/io.h> 471da177e4SLinus Torvalds #include <asm/hwrpb.h> 481da177e4SLinus Torvalds #include <asm/8253pit.h> 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds #include <linux/mc146818rtc.h> 511da177e4SLinus Torvalds #include <linux/time.h> 521da177e4SLinus Torvalds #include <linux/timex.h> 531da177e4SLinus Torvalds 541da177e4SLinus Torvalds #include "proto.h" 551da177e4SLinus Torvalds #include "irq_impl.h" 561da177e4SLinus Torvalds 571da177e4SLinus Torvalds static int set_rtc_mmss(unsigned long); 581da177e4SLinus Torvalds 591da177e4SLinus Torvalds DEFINE_SPINLOCK(rtc_lock); 601da177e4SLinus Torvalds 611da177e4SLinus Torvalds #define TICK_SIZE (tick_nsec / 1000) 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds /* 641da177e4SLinus Torvalds * Shift amount by which scaled_ticks_per_cycle is scaled. Shifting 651da177e4SLinus Torvalds * by 48 gives us 16 bits for HZ while keeping the accuracy good even 661da177e4SLinus Torvalds * for large CPU clock rates. 671da177e4SLinus Torvalds */ 681da177e4SLinus Torvalds #define FIX_SHIFT 48 691da177e4SLinus Torvalds 701da177e4SLinus Torvalds /* lump static variables together for more efficient access: */ 711da177e4SLinus Torvalds static struct { 721da177e4SLinus Torvalds /* cycle counter last time it got invoked */ 731da177e4SLinus Torvalds __u32 last_time; 741da177e4SLinus Torvalds /* ticks/cycle * 2^48 */ 751da177e4SLinus Torvalds unsigned long scaled_ticks_per_cycle; 761da177e4SLinus Torvalds /* last time the CMOS clock got updated */ 771da177e4SLinus Torvalds time_t last_rtc_update; 781da177e4SLinus Torvalds /* partial unused tick */ 791da177e4SLinus Torvalds unsigned long partial_tick; 801da177e4SLinus Torvalds } state; 811da177e4SLinus Torvalds 821da177e4SLinus Torvalds unsigned long est_cycle_freq; 831da177e4SLinus Torvalds 841da177e4SLinus Torvalds 851da177e4SLinus Torvalds static inline __u32 rpcc(void) 861da177e4SLinus Torvalds { 871da177e4SLinus Torvalds __u32 result; 881da177e4SLinus Torvalds asm volatile ("rpcc %0" : "=r"(result)); 891da177e4SLinus Torvalds return result; 901da177e4SLinus Torvalds } 911da177e4SLinus Torvalds 921da177e4SLinus Torvalds /* 931da177e4SLinus Torvalds * Scheduler clock - returns current time in nanosec units. 941da177e4SLinus Torvalds * 951da177e4SLinus Torvalds * Copied from ARM code for expediency... ;-} 961da177e4SLinus Torvalds */ 971da177e4SLinus Torvalds unsigned long long sched_clock(void) 981da177e4SLinus Torvalds { 991da177e4SLinus Torvalds return (unsigned long long)jiffies * (1000000000 / HZ); 1001da177e4SLinus Torvalds } 1011da177e4SLinus Torvalds 1021da177e4SLinus Torvalds 1031da177e4SLinus Torvalds /* 1041da177e4SLinus Torvalds * timer_interrupt() needs to keep up the real-time clock, 1051da177e4SLinus Torvalds * as well as call the "do_timer()" routine every clocktick 1061da177e4SLinus Torvalds */ 1078774cb81SAl Viro irqreturn_t timer_interrupt(int irq, void *dev) 1081da177e4SLinus Torvalds { 1091da177e4SLinus Torvalds unsigned long delta; 1101da177e4SLinus Torvalds __u32 now; 1111da177e4SLinus Torvalds long nticks; 1121da177e4SLinus Torvalds 1131da177e4SLinus Torvalds #ifndef CONFIG_SMP 1141da177e4SLinus Torvalds /* Not SMP, do kernel PC profiling here. */ 1158774cb81SAl Viro profile_tick(CPU_PROFILING); 1161da177e4SLinus Torvalds #endif 1171da177e4SLinus Torvalds 1181da177e4SLinus Torvalds write_seqlock(&xtime_lock); 1191da177e4SLinus Torvalds 1201da177e4SLinus Torvalds /* 1211da177e4SLinus Torvalds * Calculate how many ticks have passed since the last update, 1221da177e4SLinus Torvalds * including any previous partial leftover. Save any resulting 1231da177e4SLinus Torvalds * fraction for the next pass. 1241da177e4SLinus Torvalds */ 1251da177e4SLinus Torvalds now = rpcc(); 1261da177e4SLinus Torvalds delta = now - state.last_time; 1271da177e4SLinus Torvalds state.last_time = now; 1281da177e4SLinus Torvalds delta = delta * state.scaled_ticks_per_cycle + state.partial_tick; 1291da177e4SLinus Torvalds state.partial_tick = delta & ((1UL << FIX_SHIFT) - 1); 1301da177e4SLinus Torvalds nticks = delta >> FIX_SHIFT; 1311da177e4SLinus Torvalds 1321da177e4SLinus Torvalds while (nticks > 0) { 1333171a030SAtsushi Nemoto do_timer(1); 1341da177e4SLinus Torvalds #ifndef CONFIG_SMP 1358774cb81SAl Viro update_process_times(user_mode(get_irq_regs())); 1361da177e4SLinus Torvalds #endif 1371da177e4SLinus Torvalds nticks--; 1381da177e4SLinus Torvalds } 1391da177e4SLinus Torvalds 1401da177e4SLinus Torvalds /* 1411da177e4SLinus Torvalds * If we have an externally synchronized Linux clock, then update 1421da177e4SLinus Torvalds * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be 1431da177e4SLinus Torvalds * called as close as possible to 500 ms before the new second starts. 1441da177e4SLinus Torvalds */ 145b149ee22Sjohn stultz if (ntp_synced() 1461da177e4SLinus Torvalds && xtime.tv_sec > state.last_rtc_update + 660 1471da177e4SLinus Torvalds && xtime.tv_nsec >= 500000 - ((unsigned) TICK_SIZE) / 2 1481da177e4SLinus Torvalds && xtime.tv_nsec <= 500000 + ((unsigned) TICK_SIZE) / 2) { 1491da177e4SLinus Torvalds int tmp = set_rtc_mmss(xtime.tv_sec); 1501da177e4SLinus Torvalds state.last_rtc_update = xtime.tv_sec - (tmp ? 600 : 0); 1511da177e4SLinus Torvalds } 1521da177e4SLinus Torvalds 1531da177e4SLinus Torvalds write_sequnlock(&xtime_lock); 1541da177e4SLinus Torvalds return IRQ_HANDLED; 1551da177e4SLinus Torvalds } 1561da177e4SLinus Torvalds 1571da177e4SLinus Torvalds void 1581da177e4SLinus Torvalds common_init_rtc(void) 1591da177e4SLinus Torvalds { 1601da177e4SLinus Torvalds unsigned char x; 1611da177e4SLinus Torvalds 1621da177e4SLinus Torvalds /* Reset periodic interrupt frequency. */ 1631da177e4SLinus Torvalds x = CMOS_READ(RTC_FREQ_SELECT) & 0x3f; 1641da177e4SLinus Torvalds /* Test includes known working values on various platforms 1651da177e4SLinus Torvalds where 0x26 is wrong; we refuse to change those. */ 1661da177e4SLinus Torvalds if (x != 0x26 && x != 0x25 && x != 0x19 && x != 0x06) { 1671da177e4SLinus Torvalds printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x); 1681da177e4SLinus Torvalds CMOS_WRITE(0x26, RTC_FREQ_SELECT); 1691da177e4SLinus Torvalds } 1701da177e4SLinus Torvalds 1711da177e4SLinus Torvalds /* Turn on periodic interrupts. */ 1721da177e4SLinus Torvalds x = CMOS_READ(RTC_CONTROL); 1731da177e4SLinus Torvalds if (!(x & RTC_PIE)) { 1741da177e4SLinus Torvalds printk("Turning on RTC interrupts.\n"); 1751da177e4SLinus Torvalds x |= RTC_PIE; 1761da177e4SLinus Torvalds x &= ~(RTC_AIE | RTC_UIE); 1771da177e4SLinus Torvalds CMOS_WRITE(x, RTC_CONTROL); 1781da177e4SLinus Torvalds } 1791da177e4SLinus Torvalds (void) CMOS_READ(RTC_INTR_FLAGS); 1801da177e4SLinus Torvalds 1811da177e4SLinus Torvalds outb(0x36, 0x43); /* pit counter 0: system timer */ 1821da177e4SLinus Torvalds outb(0x00, 0x40); 1831da177e4SLinus Torvalds outb(0x00, 0x40); 1841da177e4SLinus Torvalds 1851da177e4SLinus Torvalds outb(0xb6, 0x43); /* pit counter 2: speaker */ 1861da177e4SLinus Torvalds outb(0x31, 0x42); 1871da177e4SLinus Torvalds outb(0x13, 0x42); 1881da177e4SLinus Torvalds 1891da177e4SLinus Torvalds init_rtc_irq(); 1901da177e4SLinus Torvalds } 1911da177e4SLinus Torvalds 1921da177e4SLinus Torvalds 1931da177e4SLinus Torvalds /* Validate a computed cycle counter result against the known bounds for 1941da177e4SLinus Torvalds the given processor core. There's too much brokenness in the way of 1951da177e4SLinus Torvalds timing hardware for any one method to work everywhere. :-( 1961da177e4SLinus Torvalds 1971da177e4SLinus Torvalds Return 0 if the result cannot be trusted, otherwise return the argument. */ 1981da177e4SLinus Torvalds 1991da177e4SLinus Torvalds static unsigned long __init 2001da177e4SLinus Torvalds validate_cc_value(unsigned long cc) 2011da177e4SLinus Torvalds { 2021da177e4SLinus Torvalds static struct bounds { 2031da177e4SLinus Torvalds unsigned int min, max; 2041da177e4SLinus Torvalds } cpu_hz[] __initdata = { 2051da177e4SLinus Torvalds [EV3_CPU] = { 50000000, 200000000 }, /* guess */ 2061da177e4SLinus Torvalds [EV4_CPU] = { 100000000, 300000000 }, 2071da177e4SLinus Torvalds [LCA4_CPU] = { 100000000, 300000000 }, /* guess */ 2081da177e4SLinus Torvalds [EV45_CPU] = { 200000000, 300000000 }, 2091da177e4SLinus Torvalds [EV5_CPU] = { 250000000, 433000000 }, 2101da177e4SLinus Torvalds [EV56_CPU] = { 333000000, 667000000 }, 2111da177e4SLinus Torvalds [PCA56_CPU] = { 400000000, 600000000 }, /* guess */ 2121da177e4SLinus Torvalds [PCA57_CPU] = { 500000000, 600000000 }, /* guess */ 2131da177e4SLinus Torvalds [EV6_CPU] = { 466000000, 600000000 }, 2141da177e4SLinus Torvalds [EV67_CPU] = { 600000000, 750000000 }, 2151da177e4SLinus Torvalds [EV68AL_CPU] = { 750000000, 940000000 }, 2161da177e4SLinus Torvalds [EV68CB_CPU] = { 1000000000, 1333333333 }, 2171da177e4SLinus Torvalds /* None of the following are shipping as of 2001-11-01. */ 2181da177e4SLinus Torvalds [EV68CX_CPU] = { 1000000000, 1700000000 }, /* guess */ 2191da177e4SLinus Torvalds [EV69_CPU] = { 1000000000, 1700000000 }, /* guess */ 2201da177e4SLinus Torvalds [EV7_CPU] = { 800000000, 1400000000 }, /* guess */ 2211da177e4SLinus Torvalds [EV79_CPU] = { 1000000000, 2000000000 }, /* guess */ 2221da177e4SLinus Torvalds }; 2231da177e4SLinus Torvalds 2241da177e4SLinus Torvalds /* Allow for some drift in the crystal. 10MHz is more than enough. */ 2251da177e4SLinus Torvalds const unsigned int deviation = 10000000; 2261da177e4SLinus Torvalds 2271da177e4SLinus Torvalds struct percpu_struct *cpu; 2281da177e4SLinus Torvalds unsigned int index; 2291da177e4SLinus Torvalds 2301da177e4SLinus Torvalds cpu = (struct percpu_struct *)((char*)hwrpb + hwrpb->processor_offset); 2311da177e4SLinus Torvalds index = cpu->type & 0xffffffff; 2321da177e4SLinus Torvalds 2331da177e4SLinus Torvalds /* If index out of bounds, no way to validate. */ 23425c8716cSTobias Klauser if (index >= ARRAY_SIZE(cpu_hz)) 2351da177e4SLinus Torvalds return cc; 2361da177e4SLinus Torvalds 2371da177e4SLinus Torvalds /* If index contains no data, no way to validate. */ 2381da177e4SLinus Torvalds if (cpu_hz[index].max == 0) 2391da177e4SLinus Torvalds return cc; 2401da177e4SLinus Torvalds 2411da177e4SLinus Torvalds if (cc < cpu_hz[index].min - deviation 2421da177e4SLinus Torvalds || cc > cpu_hz[index].max + deviation) 2431da177e4SLinus Torvalds return 0; 2441da177e4SLinus Torvalds 2451da177e4SLinus Torvalds return cc; 2461da177e4SLinus Torvalds } 2471da177e4SLinus Torvalds 2481da177e4SLinus Torvalds 2491da177e4SLinus Torvalds /* 2501da177e4SLinus Torvalds * Calibrate CPU clock using legacy 8254 timer/counter. Stolen from 2511da177e4SLinus Torvalds * arch/i386/time.c. 2521da177e4SLinus Torvalds */ 2531da177e4SLinus Torvalds 2541da177e4SLinus Torvalds #define CALIBRATE_LATCH 0xffff 2551da177e4SLinus Torvalds #define TIMEOUT_COUNT 0x100000 2561da177e4SLinus Torvalds 2571da177e4SLinus Torvalds static unsigned long __init 2581da177e4SLinus Torvalds calibrate_cc_with_pit(void) 2591da177e4SLinus Torvalds { 2601da177e4SLinus Torvalds int cc, count = 0; 2611da177e4SLinus Torvalds 2621da177e4SLinus Torvalds /* Set the Gate high, disable speaker */ 2631da177e4SLinus Torvalds outb((inb(0x61) & ~0x02) | 0x01, 0x61); 2641da177e4SLinus Torvalds 2651da177e4SLinus Torvalds /* 2661da177e4SLinus Torvalds * Now let's take care of CTC channel 2 2671da177e4SLinus Torvalds * 2681da177e4SLinus Torvalds * Set the Gate high, program CTC channel 2 for mode 0, 2691da177e4SLinus Torvalds * (interrupt on terminal count mode), binary count, 2701da177e4SLinus Torvalds * load 5 * LATCH count, (LSB and MSB) to begin countdown. 2711da177e4SLinus Torvalds */ 2721da177e4SLinus Torvalds outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */ 2731da177e4SLinus Torvalds outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */ 2741da177e4SLinus Torvalds outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */ 2751da177e4SLinus Torvalds 2761da177e4SLinus Torvalds cc = rpcc(); 2771da177e4SLinus Torvalds do { 2781da177e4SLinus Torvalds count++; 2791da177e4SLinus Torvalds } while ((inb(0x61) & 0x20) == 0 && count < TIMEOUT_COUNT); 2801da177e4SLinus Torvalds cc = rpcc() - cc; 2811da177e4SLinus Torvalds 2821da177e4SLinus Torvalds /* Error: ECTCNEVERSET or ECPUTOOFAST. */ 2831da177e4SLinus Torvalds if (count <= 1 || count == TIMEOUT_COUNT) 2841da177e4SLinus Torvalds return 0; 2851da177e4SLinus Torvalds 2861da177e4SLinus Torvalds return ((long)cc * PIT_TICK_RATE) / (CALIBRATE_LATCH + 1); 2871da177e4SLinus Torvalds } 2881da177e4SLinus Torvalds 2891da177e4SLinus Torvalds /* The Linux interpretation of the CMOS clock register contents: 2901da177e4SLinus Torvalds When the Update-In-Progress (UIP) flag goes from 1 to 0, the 2911da177e4SLinus Torvalds RTC registers show the second which has precisely just started. 2921da177e4SLinus Torvalds Let's hope other operating systems interpret the RTC the same way. */ 2931da177e4SLinus Torvalds 2941da177e4SLinus Torvalds static unsigned long __init 2951da177e4SLinus Torvalds rpcc_after_update_in_progress(void) 2961da177e4SLinus Torvalds { 2971da177e4SLinus Torvalds do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)); 2981da177e4SLinus Torvalds do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); 2991da177e4SLinus Torvalds 3001da177e4SLinus Torvalds return rpcc(); 3011da177e4SLinus Torvalds } 3021da177e4SLinus Torvalds 3031da177e4SLinus Torvalds void __init 3041da177e4SLinus Torvalds time_init(void) 3051da177e4SLinus Torvalds { 3061da177e4SLinus Torvalds unsigned int year, mon, day, hour, min, sec, cc1, cc2, epoch; 3071da177e4SLinus Torvalds unsigned long cycle_freq, tolerance; 3081da177e4SLinus Torvalds long diff; 3091da177e4SLinus Torvalds 3101da177e4SLinus Torvalds /* Calibrate CPU clock -- attempt #1. */ 3111da177e4SLinus Torvalds if (!est_cycle_freq) 3121da177e4SLinus Torvalds est_cycle_freq = validate_cc_value(calibrate_cc_with_pit()); 3131da177e4SLinus Torvalds 3144c2e6f6aSMatt Mackall cc1 = rpcc(); 3151da177e4SLinus Torvalds 3161da177e4SLinus Torvalds /* Calibrate CPU clock -- attempt #2. */ 3171da177e4SLinus Torvalds if (!est_cycle_freq) { 3184c2e6f6aSMatt Mackall cc1 = rpcc_after_update_in_progress(); 3191da177e4SLinus Torvalds cc2 = rpcc_after_update_in_progress(); 3201da177e4SLinus Torvalds est_cycle_freq = validate_cc_value(cc2 - cc1); 3211da177e4SLinus Torvalds cc1 = cc2; 3221da177e4SLinus Torvalds } 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds cycle_freq = hwrpb->cycle_freq; 3251da177e4SLinus Torvalds if (est_cycle_freq) { 3261da177e4SLinus Torvalds /* If the given value is within 250 PPM of what we calculated, 3271da177e4SLinus Torvalds accept it. Otherwise, use what we found. */ 3281da177e4SLinus Torvalds tolerance = cycle_freq / 4000; 3291da177e4SLinus Torvalds diff = cycle_freq - est_cycle_freq; 3301da177e4SLinus Torvalds if (diff < 0) 3311da177e4SLinus Torvalds diff = -diff; 3321da177e4SLinus Torvalds if ((unsigned long)diff > tolerance) { 3331da177e4SLinus Torvalds cycle_freq = est_cycle_freq; 3341da177e4SLinus Torvalds printk("HWRPB cycle frequency bogus. " 3351da177e4SLinus Torvalds "Estimated %lu Hz\n", cycle_freq); 3361da177e4SLinus Torvalds } else { 3371da177e4SLinus Torvalds est_cycle_freq = 0; 3381da177e4SLinus Torvalds } 3391da177e4SLinus Torvalds } else if (! validate_cc_value (cycle_freq)) { 3401da177e4SLinus Torvalds printk("HWRPB cycle frequency bogus, " 3411da177e4SLinus Torvalds "and unable to estimate a proper value!\n"); 3421da177e4SLinus Torvalds } 3431da177e4SLinus Torvalds 3441da177e4SLinus Torvalds /* From John Bowman <bowman@math.ualberta.ca>: allow the values 3451da177e4SLinus Torvalds to settle, as the Update-In-Progress bit going low isn't good 3461da177e4SLinus Torvalds enough on some hardware. 2ms is our guess; we haven't found 3471da177e4SLinus Torvalds bogomips yet, but this is close on a 500Mhz box. */ 3481da177e4SLinus Torvalds __delay(1000000); 3491da177e4SLinus Torvalds 3501da177e4SLinus Torvalds sec = CMOS_READ(RTC_SECONDS); 3511da177e4SLinus Torvalds min = CMOS_READ(RTC_MINUTES); 3521da177e4SLinus Torvalds hour = CMOS_READ(RTC_HOURS); 3531da177e4SLinus Torvalds day = CMOS_READ(RTC_DAY_OF_MONTH); 3541da177e4SLinus Torvalds mon = CMOS_READ(RTC_MONTH); 3551da177e4SLinus Torvalds year = CMOS_READ(RTC_YEAR); 3561da177e4SLinus Torvalds 3571da177e4SLinus Torvalds if (!(CMOS_READ(RTC_CONTROL) & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 3581da177e4SLinus Torvalds BCD_TO_BIN(sec); 3591da177e4SLinus Torvalds BCD_TO_BIN(min); 3601da177e4SLinus Torvalds BCD_TO_BIN(hour); 3611da177e4SLinus Torvalds BCD_TO_BIN(day); 3621da177e4SLinus Torvalds BCD_TO_BIN(mon); 3631da177e4SLinus Torvalds BCD_TO_BIN(year); 3641da177e4SLinus Torvalds } 3651da177e4SLinus Torvalds 3661da177e4SLinus Torvalds /* PC-like is standard; used for year >= 70 */ 3671da177e4SLinus Torvalds epoch = 1900; 3681da177e4SLinus Torvalds if (year < 20) 3691da177e4SLinus Torvalds epoch = 2000; 3701da177e4SLinus Torvalds else if (year >= 20 && year < 48) 3711da177e4SLinus Torvalds /* NT epoch */ 3721da177e4SLinus Torvalds epoch = 1980; 3731da177e4SLinus Torvalds else if (year >= 48 && year < 70) 3741da177e4SLinus Torvalds /* Digital UNIX epoch */ 3751da177e4SLinus Torvalds epoch = 1952; 3761da177e4SLinus Torvalds 3771da177e4SLinus Torvalds printk(KERN_INFO "Using epoch = %d\n", epoch); 3781da177e4SLinus Torvalds 3791da177e4SLinus Torvalds if ((year += epoch) < 1970) 3801da177e4SLinus Torvalds year += 100; 3811da177e4SLinus Torvalds 3821da177e4SLinus Torvalds xtime.tv_sec = mktime(year, mon, day, hour, min, sec); 3831da177e4SLinus Torvalds xtime.tv_nsec = 0; 3841da177e4SLinus Torvalds 3851da177e4SLinus Torvalds wall_to_monotonic.tv_sec -= xtime.tv_sec; 3861da177e4SLinus Torvalds wall_to_monotonic.tv_nsec = 0; 3871da177e4SLinus Torvalds 3881da177e4SLinus Torvalds if (HZ > (1<<16)) { 3891da177e4SLinus Torvalds extern void __you_loose (void); 3901da177e4SLinus Torvalds __you_loose(); 3911da177e4SLinus Torvalds } 3921da177e4SLinus Torvalds 3931da177e4SLinus Torvalds state.last_time = cc1; 3941da177e4SLinus Torvalds state.scaled_ticks_per_cycle 3951da177e4SLinus Torvalds = ((unsigned long) HZ << FIX_SHIFT) / cycle_freq; 3961da177e4SLinus Torvalds state.last_rtc_update = 0; 3971da177e4SLinus Torvalds state.partial_tick = 0L; 3981da177e4SLinus Torvalds 3991da177e4SLinus Torvalds /* Startup the timer source. */ 4001da177e4SLinus Torvalds alpha_mv.init_rtc(); 4011da177e4SLinus Torvalds } 4021da177e4SLinus Torvalds 4031da177e4SLinus Torvalds /* 4041da177e4SLinus Torvalds * Use the cycle counter to estimate an displacement from the last time 4051da177e4SLinus Torvalds * tick. Unfortunately the Alpha designers made only the low 32-bits of 4061da177e4SLinus Torvalds * the cycle counter active, so we overflow on 8.2 seconds on a 500MHz 4071da177e4SLinus Torvalds * part. So we can't do the "find absolute time in terms of cycles" thing 4081da177e4SLinus Torvalds * that the other ports do. 4091da177e4SLinus Torvalds */ 4101da177e4SLinus Torvalds void 4111da177e4SLinus Torvalds do_gettimeofday(struct timeval *tv) 4121da177e4SLinus Torvalds { 4131da177e4SLinus Torvalds unsigned long flags; 4148ef38609SAtsushi Nemoto unsigned long sec, usec, seq; 4151da177e4SLinus Torvalds unsigned long delta_cycles, delta_usec, partial_tick; 4161da177e4SLinus Torvalds 4171da177e4SLinus Torvalds do { 4181da177e4SLinus Torvalds seq = read_seqbegin_irqsave(&xtime_lock, flags); 4191da177e4SLinus Torvalds 4201da177e4SLinus Torvalds delta_cycles = rpcc() - state.last_time; 4211da177e4SLinus Torvalds sec = xtime.tv_sec; 4221da177e4SLinus Torvalds usec = (xtime.tv_nsec / 1000); 4231da177e4SLinus Torvalds partial_tick = state.partial_tick; 4241da177e4SLinus Torvalds 4251da177e4SLinus Torvalds } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); 4261da177e4SLinus Torvalds 4271da177e4SLinus Torvalds #ifdef CONFIG_SMP 4281da177e4SLinus Torvalds /* Until and unless we figure out how to get cpu cycle counters 4291da177e4SLinus Torvalds in sync and keep them there, we can't use the rpcc tricks. */ 4308ef38609SAtsushi Nemoto delta_usec = 0; 4311da177e4SLinus Torvalds #else 4321da177e4SLinus Torvalds /* 4331da177e4SLinus Torvalds * usec = cycles * ticks_per_cycle * 2**48 * 1e6 / (2**48 * ticks) 4341da177e4SLinus Torvalds * = cycles * (s_t_p_c) * 1e6 / (2**48 * ticks) 4351da177e4SLinus Torvalds * = cycles * (s_t_p_c) * 15625 / (2**42 * ticks) 4361da177e4SLinus Torvalds * 4371da177e4SLinus Torvalds * which, given a 600MHz cycle and a 1024Hz tick, has a 4381da177e4SLinus Torvalds * dynamic range of about 1.7e17, which is less than the 4391da177e4SLinus Torvalds * 1.8e19 in an unsigned long, so we are safe from overflow. 4401da177e4SLinus Torvalds * 4411da177e4SLinus Torvalds * Round, but with .5 up always, since .5 to even is harder 4421da177e4SLinus Torvalds * with no clear gain. 4431da177e4SLinus Torvalds */ 4441da177e4SLinus Torvalds 4451da177e4SLinus Torvalds delta_usec = (delta_cycles * state.scaled_ticks_per_cycle 4468ef38609SAtsushi Nemoto + partial_tick) * 15625; 4471da177e4SLinus Torvalds delta_usec = ((delta_usec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; 4481da177e4SLinus Torvalds #endif 4491da177e4SLinus Torvalds 4501da177e4SLinus Torvalds usec += delta_usec; 4511da177e4SLinus Torvalds if (usec >= 1000000) { 4521da177e4SLinus Torvalds sec += 1; 4531da177e4SLinus Torvalds usec -= 1000000; 4541da177e4SLinus Torvalds } 4551da177e4SLinus Torvalds 4561da177e4SLinus Torvalds tv->tv_sec = sec; 4571da177e4SLinus Torvalds tv->tv_usec = usec; 4581da177e4SLinus Torvalds } 4591da177e4SLinus Torvalds 4601da177e4SLinus Torvalds EXPORT_SYMBOL(do_gettimeofday); 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds int 4631da177e4SLinus Torvalds do_settimeofday(struct timespec *tv) 4641da177e4SLinus Torvalds { 4651da177e4SLinus Torvalds time_t wtm_sec, sec = tv->tv_sec; 4661da177e4SLinus Torvalds long wtm_nsec, nsec = tv->tv_nsec; 4671da177e4SLinus Torvalds unsigned long delta_nsec; 4681da177e4SLinus Torvalds 4691da177e4SLinus Torvalds if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) 4701da177e4SLinus Torvalds return -EINVAL; 4711da177e4SLinus Torvalds 4721da177e4SLinus Torvalds write_seqlock_irq(&xtime_lock); 4731da177e4SLinus Torvalds 4741da177e4SLinus Torvalds /* The offset that is added into time in do_gettimeofday above 4751da177e4SLinus Torvalds must be subtracted out here to keep a coherent view of the 4761da177e4SLinus Torvalds time. Without this, a full-tick error is possible. */ 4771da177e4SLinus Torvalds 4781da177e4SLinus Torvalds #ifdef CONFIG_SMP 4798ef38609SAtsushi Nemoto delta_nsec = 0; 4801da177e4SLinus Torvalds #else 4811da177e4SLinus Torvalds delta_nsec = rpcc() - state.last_time; 4821da177e4SLinus Torvalds delta_nsec = (delta_nsec * state.scaled_ticks_per_cycle 4838ef38609SAtsushi Nemoto + state.partial_tick) * 15625; 4841da177e4SLinus Torvalds delta_nsec = ((delta_nsec / ((1UL << (FIX_SHIFT-6-1)) * HZ)) + 1) / 2; 4851da177e4SLinus Torvalds delta_nsec *= 1000; 4861da177e4SLinus Torvalds #endif 4871da177e4SLinus Torvalds 4881da177e4SLinus Torvalds nsec -= delta_nsec; 4891da177e4SLinus Torvalds 4901da177e4SLinus Torvalds wtm_sec = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec); 4911da177e4SLinus Torvalds wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec); 4921da177e4SLinus Torvalds 4931da177e4SLinus Torvalds set_normalized_timespec(&xtime, sec, nsec); 4941da177e4SLinus Torvalds set_normalized_timespec(&wall_to_monotonic, wtm_sec, wtm_nsec); 4951da177e4SLinus Torvalds 496b149ee22Sjohn stultz ntp_clear(); 4971da177e4SLinus Torvalds 4981da177e4SLinus Torvalds write_sequnlock_irq(&xtime_lock); 4991da177e4SLinus Torvalds clock_was_set(); 5001da177e4SLinus Torvalds return 0; 5011da177e4SLinus Torvalds } 5021da177e4SLinus Torvalds 5031da177e4SLinus Torvalds EXPORT_SYMBOL(do_settimeofday); 5041da177e4SLinus Torvalds 5051da177e4SLinus Torvalds 5061da177e4SLinus Torvalds /* 5071da177e4SLinus Torvalds * In order to set the CMOS clock precisely, set_rtc_mmss has to be 5081da177e4SLinus Torvalds * called 500 ms after the second nowtime has started, because when 5091da177e4SLinus Torvalds * nowtime is written into the registers of the CMOS clock, it will 5101da177e4SLinus Torvalds * jump to the next second precisely 500 ms later. Check the Motorola 5111da177e4SLinus Torvalds * MC146818A or Dallas DS12887 data sheet for details. 5121da177e4SLinus Torvalds * 5131da177e4SLinus Torvalds * BUG: This routine does not handle hour overflow properly; it just 5141da177e4SLinus Torvalds * sets the minutes. Usually you won't notice until after reboot! 5151da177e4SLinus Torvalds */ 5161da177e4SLinus Torvalds 5171da177e4SLinus Torvalds 5181da177e4SLinus Torvalds static int 5191da177e4SLinus Torvalds set_rtc_mmss(unsigned long nowtime) 5201da177e4SLinus Torvalds { 5211da177e4SLinus Torvalds int retval = 0; 5221da177e4SLinus Torvalds int real_seconds, real_minutes, cmos_minutes; 5231da177e4SLinus Torvalds unsigned char save_control, save_freq_select; 5241da177e4SLinus Torvalds 5251da177e4SLinus Torvalds /* irq are locally disabled here */ 5261da177e4SLinus Torvalds spin_lock(&rtc_lock); 5271da177e4SLinus Torvalds /* Tell the clock it's being set */ 5281da177e4SLinus Torvalds save_control = CMOS_READ(RTC_CONTROL); 5291da177e4SLinus Torvalds CMOS_WRITE((save_control|RTC_SET), RTC_CONTROL); 5301da177e4SLinus Torvalds 5311da177e4SLinus Torvalds /* Stop and reset prescaler */ 5321da177e4SLinus Torvalds save_freq_select = CMOS_READ(RTC_FREQ_SELECT); 5331da177e4SLinus Torvalds CMOS_WRITE((save_freq_select|RTC_DIV_RESET2), RTC_FREQ_SELECT); 5341da177e4SLinus Torvalds 5351da177e4SLinus Torvalds cmos_minutes = CMOS_READ(RTC_MINUTES); 5361da177e4SLinus Torvalds if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) 5371da177e4SLinus Torvalds BCD_TO_BIN(cmos_minutes); 5381da177e4SLinus Torvalds 5391da177e4SLinus Torvalds /* 5401da177e4SLinus Torvalds * since we're only adjusting minutes and seconds, 5411da177e4SLinus Torvalds * don't interfere with hour overflow. This avoids 5421da177e4SLinus Torvalds * messing with unknown time zones but requires your 5431da177e4SLinus Torvalds * RTC not to be off by more than 15 minutes 5441da177e4SLinus Torvalds */ 5451da177e4SLinus Torvalds real_seconds = nowtime % 60; 5461da177e4SLinus Torvalds real_minutes = nowtime / 60; 5471da177e4SLinus Torvalds if (((abs(real_minutes - cmos_minutes) + 15)/30) & 1) { 5481da177e4SLinus Torvalds /* correct for half hour time zone */ 5491da177e4SLinus Torvalds real_minutes += 30; 5501da177e4SLinus Torvalds } 5511da177e4SLinus Torvalds real_minutes %= 60; 5521da177e4SLinus Torvalds 5531da177e4SLinus Torvalds if (abs(real_minutes - cmos_minutes) < 30) { 5541da177e4SLinus Torvalds if (!(save_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { 5551da177e4SLinus Torvalds BIN_TO_BCD(real_seconds); 5561da177e4SLinus Torvalds BIN_TO_BCD(real_minutes); 5571da177e4SLinus Torvalds } 5581da177e4SLinus Torvalds CMOS_WRITE(real_seconds,RTC_SECONDS); 5591da177e4SLinus Torvalds CMOS_WRITE(real_minutes,RTC_MINUTES); 5601da177e4SLinus Torvalds } else { 5611da177e4SLinus Torvalds printk(KERN_WARNING 5621da177e4SLinus Torvalds "set_rtc_mmss: can't update from %d to %d\n", 5631da177e4SLinus Torvalds cmos_minutes, real_minutes); 5641da177e4SLinus Torvalds retval = -1; 5651da177e4SLinus Torvalds } 5661da177e4SLinus Torvalds 5671da177e4SLinus Torvalds /* The following flags have to be released exactly in this order, 5681da177e4SLinus Torvalds * otherwise the DS12887 (popular MC146818A clone with integrated 5691da177e4SLinus Torvalds * battery and quartz) will not reset the oscillator and will not 5701da177e4SLinus Torvalds * update precisely 500 ms later. You won't find this mentioned in 5711da177e4SLinus Torvalds * the Dallas Semiconductor data sheets, but who believes data 5721da177e4SLinus Torvalds * sheets anyway ... -- Markus Kuhn 5731da177e4SLinus Torvalds */ 5741da177e4SLinus Torvalds CMOS_WRITE(save_control, RTC_CONTROL); 5751da177e4SLinus Torvalds CMOS_WRITE(save_freq_select, RTC_FREQ_SELECT); 5761da177e4SLinus Torvalds spin_unlock(&rtc_lock); 5771da177e4SLinus Torvalds 5781da177e4SLinus Torvalds return retval; 5791da177e4SLinus Torvalds } 580