1bfc0f594SAlok Kataria #include <linux/kernel.h> 20ef95533SAlok Kataria #include <linux/sched.h> 30ef95533SAlok Kataria #include <linux/init.h> 40ef95533SAlok Kataria #include <linux/module.h> 50ef95533SAlok Kataria #include <linux/timer.h> 6bfc0f594SAlok Kataria #include <linux/acpi_pmtmr.h> 72dbe06faSAlok Kataria #include <linux/cpufreq.h> 88fbbc4b4SAlok Kataria #include <linux/dmi.h> 98fbbc4b4SAlok Kataria #include <linux/delay.h> 108fbbc4b4SAlok Kataria #include <linux/clocksource.h> 118fbbc4b4SAlok Kataria #include <linux/percpu.h> 12bfc0f594SAlok Kataria 13bfc0f594SAlok Kataria #include <asm/hpet.h> 148fbbc4b4SAlok Kataria #include <asm/timer.h> 158fbbc4b4SAlok Kataria #include <asm/vgtod.h> 168fbbc4b4SAlok Kataria #include <asm/time.h> 178fbbc4b4SAlok Kataria #include <asm/delay.h> 180ef95533SAlok Kataria 190ef95533SAlok Kataria unsigned int cpu_khz; /* TSC clocks / usec, not used here */ 200ef95533SAlok Kataria EXPORT_SYMBOL(cpu_khz); 210ef95533SAlok Kataria unsigned int tsc_khz; 220ef95533SAlok Kataria EXPORT_SYMBOL(tsc_khz); 230ef95533SAlok Kataria 240ef95533SAlok Kataria /* 250ef95533SAlok Kataria * TSC can be unstable due to cpufreq or due to unsynced TSCs 260ef95533SAlok Kataria */ 278fbbc4b4SAlok Kataria static int tsc_unstable; 280ef95533SAlok Kataria 290ef95533SAlok Kataria /* native_sched_clock() is called before tsc_init(), so 300ef95533SAlok Kataria we must start with the TSC soft disabled to prevent 310ef95533SAlok Kataria erroneous rdtsc usage on !cpu_has_tsc processors */ 328fbbc4b4SAlok Kataria static int tsc_disabled = -1; 330ef95533SAlok Kataria 340ef95533SAlok Kataria /* 350ef95533SAlok Kataria * Scheduler clock - returns current time in nanosec units. 360ef95533SAlok Kataria */ 370ef95533SAlok Kataria u64 native_sched_clock(void) 380ef95533SAlok Kataria { 390ef95533SAlok Kataria u64 this_offset; 400ef95533SAlok Kataria 410ef95533SAlok Kataria /* 420ef95533SAlok Kataria * Fall back to jiffies if there's no TSC available: 430ef95533SAlok Kataria * ( But note that we still use it if the TSC is marked 440ef95533SAlok Kataria * unstable. We do this because unlike Time Of Day, 450ef95533SAlok Kataria * the scheduler clock tolerates small errors and it's 460ef95533SAlok Kataria * very important for it to be as fast as the platform 470ef95533SAlok Kataria * can achive it. ) 480ef95533SAlok Kataria */ 490ef95533SAlok Kataria if (unlikely(tsc_disabled)) { 500ef95533SAlok Kataria /* No locking but a rare wrong value is not a big deal: */ 510ef95533SAlok Kataria return (jiffies_64 - INITIAL_JIFFIES) * (1000000000 / HZ); 520ef95533SAlok Kataria } 530ef95533SAlok Kataria 540ef95533SAlok Kataria /* read the Time Stamp Counter: */ 550ef95533SAlok Kataria rdtscll(this_offset); 560ef95533SAlok Kataria 570ef95533SAlok Kataria /* return the value in ns */ 580ef95533SAlok Kataria return cycles_2_ns(this_offset); 590ef95533SAlok Kataria } 600ef95533SAlok Kataria 610ef95533SAlok Kataria /* We need to define a real function for sched_clock, to override the 620ef95533SAlok Kataria weak default version */ 630ef95533SAlok Kataria #ifdef CONFIG_PARAVIRT 640ef95533SAlok Kataria unsigned long long sched_clock(void) 650ef95533SAlok Kataria { 660ef95533SAlok Kataria return paravirt_sched_clock(); 670ef95533SAlok Kataria } 680ef95533SAlok Kataria #else 690ef95533SAlok Kataria unsigned long long 700ef95533SAlok Kataria sched_clock(void) __attribute__((alias("native_sched_clock"))); 710ef95533SAlok Kataria #endif 720ef95533SAlok Kataria 730ef95533SAlok Kataria int check_tsc_unstable(void) 740ef95533SAlok Kataria { 750ef95533SAlok Kataria return tsc_unstable; 760ef95533SAlok Kataria } 770ef95533SAlok Kataria EXPORT_SYMBOL_GPL(check_tsc_unstable); 780ef95533SAlok Kataria 790ef95533SAlok Kataria #ifdef CONFIG_X86_TSC 800ef95533SAlok Kataria int __init notsc_setup(char *str) 810ef95533SAlok Kataria { 820ef95533SAlok Kataria printk(KERN_WARNING "notsc: Kernel compiled with CONFIG_X86_TSC, " 830ef95533SAlok Kataria "cannot disable TSC completely.\n"); 840ef95533SAlok Kataria tsc_disabled = 1; 850ef95533SAlok Kataria return 1; 860ef95533SAlok Kataria } 870ef95533SAlok Kataria #else 880ef95533SAlok Kataria /* 890ef95533SAlok Kataria * disable flag for tsc. Takes effect by clearing the TSC cpu flag 900ef95533SAlok Kataria * in cpu/common.c 910ef95533SAlok Kataria */ 920ef95533SAlok Kataria int __init notsc_setup(char *str) 930ef95533SAlok Kataria { 940ef95533SAlok Kataria setup_clear_cpu_cap(X86_FEATURE_TSC); 950ef95533SAlok Kataria return 1; 960ef95533SAlok Kataria } 970ef95533SAlok Kataria #endif 980ef95533SAlok Kataria 990ef95533SAlok Kataria __setup("notsc", notsc_setup); 100bfc0f594SAlok Kataria 101bfc0f594SAlok Kataria #define MAX_RETRIES 5 102bfc0f594SAlok Kataria #define SMI_TRESHOLD 50000 103bfc0f594SAlok Kataria 104bfc0f594SAlok Kataria /* 105bfc0f594SAlok Kataria * Read TSC and the reference counters. Take care of SMI disturbance 106bfc0f594SAlok Kataria */ 107d554d9a4SMarcin Slusarz static u64 tsc_read_refs(u64 *pm, u64 *hpet) 108bfc0f594SAlok Kataria { 109bfc0f594SAlok Kataria u64 t1, t2; 110bfc0f594SAlok Kataria int i; 111bfc0f594SAlok Kataria 112bfc0f594SAlok Kataria for (i = 0; i < MAX_RETRIES; i++) { 113bfc0f594SAlok Kataria t1 = get_cycles(); 114bfc0f594SAlok Kataria if (hpet) 115bfc0f594SAlok Kataria *hpet = hpet_readl(HPET_COUNTER) & 0xFFFFFFFF; 116bfc0f594SAlok Kataria else 117bfc0f594SAlok Kataria *pm = acpi_pm_read_early(); 118bfc0f594SAlok Kataria t2 = get_cycles(); 119bfc0f594SAlok Kataria if ((t2 - t1) < SMI_TRESHOLD) 120bfc0f594SAlok Kataria return t2; 121bfc0f594SAlok Kataria } 122bfc0f594SAlok Kataria return ULLONG_MAX; 123bfc0f594SAlok Kataria } 124bfc0f594SAlok Kataria 125bfc0f594SAlok Kataria /** 126e93ef949SAlok Kataria * native_calibrate_tsc - calibrate the tsc on boot 127bfc0f594SAlok Kataria */ 128e93ef949SAlok Kataria unsigned long native_calibrate_tsc(void) 129bfc0f594SAlok Kataria { 130bfc0f594SAlok Kataria unsigned long flags; 131bfc0f594SAlok Kataria u64 tsc1, tsc2, tr1, tr2, delta, pm1, pm2, hpet1, hpet2; 132bfc0f594SAlok Kataria int hpet = is_hpet_enabled(); 133bfc0f594SAlok Kataria unsigned int tsc_khz_val = 0; 134bfc0f594SAlok Kataria 135bfc0f594SAlok Kataria local_irq_save(flags); 136bfc0f594SAlok Kataria 137bfc0f594SAlok Kataria tsc1 = tsc_read_refs(&pm1, hpet ? &hpet1 : NULL); 138bfc0f594SAlok Kataria 139bfc0f594SAlok Kataria outb((inb(0x61) & ~0x02) | 0x01, 0x61); 140bfc0f594SAlok Kataria 141bfc0f594SAlok Kataria outb(0xb0, 0x43); 142bfc0f594SAlok Kataria outb((CLOCK_TICK_RATE / (1000 / 50)) & 0xff, 0x42); 143bfc0f594SAlok Kataria outb((CLOCK_TICK_RATE / (1000 / 50)) >> 8, 0x42); 144bfc0f594SAlok Kataria tr1 = get_cycles(); 145bfc0f594SAlok Kataria while ((inb(0x61) & 0x20) == 0); 146bfc0f594SAlok Kataria tr2 = get_cycles(); 147bfc0f594SAlok Kataria 148bfc0f594SAlok Kataria tsc2 = tsc_read_refs(&pm2, hpet ? &hpet2 : NULL); 149bfc0f594SAlok Kataria 150bfc0f594SAlok Kataria local_irq_restore(flags); 151bfc0f594SAlok Kataria 152bfc0f594SAlok Kataria /* 153bfc0f594SAlok Kataria * Preset the result with the raw and inaccurate PIT 154bfc0f594SAlok Kataria * calibration value 155bfc0f594SAlok Kataria */ 156bfc0f594SAlok Kataria delta = (tr2 - tr1); 157bfc0f594SAlok Kataria do_div(delta, 50); 158bfc0f594SAlok Kataria tsc_khz_val = delta; 159bfc0f594SAlok Kataria 160bfc0f594SAlok Kataria /* hpet or pmtimer available ? */ 161bfc0f594SAlok Kataria if (!hpet && !pm1 && !pm2) { 162bfc0f594SAlok Kataria printk(KERN_INFO "TSC calibrated against PIT\n"); 163bfc0f594SAlok Kataria goto out; 164bfc0f594SAlok Kataria } 165bfc0f594SAlok Kataria 166bfc0f594SAlok Kataria /* Check, whether the sampling was disturbed by an SMI */ 167bfc0f594SAlok Kataria if (tsc1 == ULLONG_MAX || tsc2 == ULLONG_MAX) { 168bfc0f594SAlok Kataria printk(KERN_WARNING "TSC calibration disturbed by SMI, " 169bfc0f594SAlok Kataria "using PIT calibration result\n"); 170bfc0f594SAlok Kataria goto out; 171bfc0f594SAlok Kataria } 172bfc0f594SAlok Kataria 173bfc0f594SAlok Kataria tsc2 = (tsc2 - tsc1) * 1000000LL; 174bfc0f594SAlok Kataria 175bfc0f594SAlok Kataria if (hpet) { 176bfc0f594SAlok Kataria printk(KERN_INFO "TSC calibrated against HPET\n"); 177bfc0f594SAlok Kataria if (hpet2 < hpet1) 178bfc0f594SAlok Kataria hpet2 += 0x100000000ULL; 179bfc0f594SAlok Kataria hpet2 -= hpet1; 180bfc0f594SAlok Kataria tsc1 = ((u64)hpet2 * hpet_readl(HPET_PERIOD)); 181bfc0f594SAlok Kataria do_div(tsc1, 1000000); 182bfc0f594SAlok Kataria } else { 183bfc0f594SAlok Kataria printk(KERN_INFO "TSC calibrated against PM_TIMER\n"); 184bfc0f594SAlok Kataria if (pm2 < pm1) 185bfc0f594SAlok Kataria pm2 += (u64)ACPI_PM_OVRRUN; 186bfc0f594SAlok Kataria pm2 -= pm1; 187bfc0f594SAlok Kataria tsc1 = pm2 * 1000000000LL; 188bfc0f594SAlok Kataria do_div(tsc1, PMTMR_TICKS_PER_SEC); 189bfc0f594SAlok Kataria } 190bfc0f594SAlok Kataria 191bfc0f594SAlok Kataria do_div(tsc2, tsc1); 192bfc0f594SAlok Kataria tsc_khz_val = tsc2; 193bfc0f594SAlok Kataria 194bfc0f594SAlok Kataria out: 195bfc0f594SAlok Kataria return tsc_khz_val; 196bfc0f594SAlok Kataria } 197bfc0f594SAlok Kataria 198bfc0f594SAlok Kataria 199bfc0f594SAlok Kataria #ifdef CONFIG_X86_32 200bfc0f594SAlok Kataria /* Only called from the Powernow K7 cpu freq driver */ 201bfc0f594SAlok Kataria int recalibrate_cpu_khz(void) 202bfc0f594SAlok Kataria { 203bfc0f594SAlok Kataria #ifndef CONFIG_SMP 204bfc0f594SAlok Kataria unsigned long cpu_khz_old = cpu_khz; 205bfc0f594SAlok Kataria 206bfc0f594SAlok Kataria if (cpu_has_tsc) { 207e93ef949SAlok Kataria tsc_khz = calibrate_tsc(); 208e93ef949SAlok Kataria cpu_khz = tsc_khz; 209bfc0f594SAlok Kataria cpu_data(0).loops_per_jiffy = 210bfc0f594SAlok Kataria cpufreq_scale(cpu_data(0).loops_per_jiffy, 211bfc0f594SAlok Kataria cpu_khz_old, cpu_khz); 212bfc0f594SAlok Kataria return 0; 213bfc0f594SAlok Kataria } else 214bfc0f594SAlok Kataria return -ENODEV; 215bfc0f594SAlok Kataria #else 216bfc0f594SAlok Kataria return -ENODEV; 217bfc0f594SAlok Kataria #endif 218bfc0f594SAlok Kataria } 219bfc0f594SAlok Kataria 220bfc0f594SAlok Kataria EXPORT_SYMBOL(recalibrate_cpu_khz); 221bfc0f594SAlok Kataria 222bfc0f594SAlok Kataria #endif /* CONFIG_X86_32 */ 2232dbe06faSAlok Kataria 2242dbe06faSAlok Kataria /* Accelerators for sched_clock() 2252dbe06faSAlok Kataria * convert from cycles(64bits) => nanoseconds (64bits) 2262dbe06faSAlok Kataria * basic equation: 2272dbe06faSAlok Kataria * ns = cycles / (freq / ns_per_sec) 2282dbe06faSAlok Kataria * ns = cycles * (ns_per_sec / freq) 2292dbe06faSAlok Kataria * ns = cycles * (10^9 / (cpu_khz * 10^3)) 2302dbe06faSAlok Kataria * ns = cycles * (10^6 / cpu_khz) 2312dbe06faSAlok Kataria * 2322dbe06faSAlok Kataria * Then we use scaling math (suggested by george@mvista.com) to get: 2332dbe06faSAlok Kataria * ns = cycles * (10^6 * SC / cpu_khz) / SC 2342dbe06faSAlok Kataria * ns = cycles * cyc2ns_scale / SC 2352dbe06faSAlok Kataria * 2362dbe06faSAlok Kataria * And since SC is a constant power of two, we can convert the div 2372dbe06faSAlok Kataria * into a shift. 2382dbe06faSAlok Kataria * 2392dbe06faSAlok Kataria * We can use khz divisor instead of mhz to keep a better precision, since 2402dbe06faSAlok Kataria * cyc2ns_scale is limited to 10^6 * 2^10, which fits in 32 bits. 2412dbe06faSAlok Kataria * (mathieu.desnoyers@polymtl.ca) 2422dbe06faSAlok Kataria * 2432dbe06faSAlok Kataria * -johnstul@us.ibm.com "math is hard, lets go shopping!" 2442dbe06faSAlok Kataria */ 2452dbe06faSAlok Kataria 2462dbe06faSAlok Kataria DEFINE_PER_CPU(unsigned long, cyc2ns); 2472dbe06faSAlok Kataria 2488fbbc4b4SAlok Kataria static void set_cyc2ns_scale(unsigned long cpu_khz, int cpu) 2492dbe06faSAlok Kataria { 2502dbe06faSAlok Kataria unsigned long long tsc_now, ns_now; 2512dbe06faSAlok Kataria unsigned long flags, *scale; 2522dbe06faSAlok Kataria 2532dbe06faSAlok Kataria local_irq_save(flags); 2542dbe06faSAlok Kataria sched_clock_idle_sleep_event(); 2552dbe06faSAlok Kataria 2562dbe06faSAlok Kataria scale = &per_cpu(cyc2ns, cpu); 2572dbe06faSAlok Kataria 2582dbe06faSAlok Kataria rdtscll(tsc_now); 2592dbe06faSAlok Kataria ns_now = __cycles_2_ns(tsc_now); 2602dbe06faSAlok Kataria 2612dbe06faSAlok Kataria if (cpu_khz) 2622dbe06faSAlok Kataria *scale = (NSEC_PER_MSEC << CYC2NS_SCALE_FACTOR)/cpu_khz; 2632dbe06faSAlok Kataria 2642dbe06faSAlok Kataria sched_clock_idle_wakeup_event(0); 2652dbe06faSAlok Kataria local_irq_restore(flags); 2662dbe06faSAlok Kataria } 2672dbe06faSAlok Kataria 2682dbe06faSAlok Kataria #ifdef CONFIG_CPU_FREQ 2692dbe06faSAlok Kataria 2702dbe06faSAlok Kataria /* Frequency scaling support. Adjust the TSC based timer when the cpu frequency 2712dbe06faSAlok Kataria * changes. 2722dbe06faSAlok Kataria * 2732dbe06faSAlok Kataria * RED-PEN: On SMP we assume all CPUs run with the same frequency. It's 2742dbe06faSAlok Kataria * not that important because current Opteron setups do not support 2752dbe06faSAlok Kataria * scaling on SMP anyroads. 2762dbe06faSAlok Kataria * 2772dbe06faSAlok Kataria * Should fix up last_tsc too. Currently gettimeofday in the 2782dbe06faSAlok Kataria * first tick after the change will be slightly wrong. 2792dbe06faSAlok Kataria */ 2802dbe06faSAlok Kataria 2812dbe06faSAlok Kataria static unsigned int ref_freq; 2822dbe06faSAlok Kataria static unsigned long loops_per_jiffy_ref; 2832dbe06faSAlok Kataria static unsigned long tsc_khz_ref; 2842dbe06faSAlok Kataria 2852dbe06faSAlok Kataria static int time_cpufreq_notifier(struct notifier_block *nb, unsigned long val, 2862dbe06faSAlok Kataria void *data) 2872dbe06faSAlok Kataria { 2882dbe06faSAlok Kataria struct cpufreq_freqs *freq = data; 2892dbe06faSAlok Kataria unsigned long *lpj, dummy; 2902dbe06faSAlok Kataria 2912dbe06faSAlok Kataria if (cpu_has(&cpu_data(freq->cpu), X86_FEATURE_CONSTANT_TSC)) 2922dbe06faSAlok Kataria return 0; 2932dbe06faSAlok Kataria 2942dbe06faSAlok Kataria lpj = &dummy; 2952dbe06faSAlok Kataria if (!(freq->flags & CPUFREQ_CONST_LOOPS)) 2962dbe06faSAlok Kataria #ifdef CONFIG_SMP 2972dbe06faSAlok Kataria lpj = &cpu_data(freq->cpu).loops_per_jiffy; 2982dbe06faSAlok Kataria #else 2992dbe06faSAlok Kataria lpj = &boot_cpu_data.loops_per_jiffy; 3002dbe06faSAlok Kataria #endif 3012dbe06faSAlok Kataria 3022dbe06faSAlok Kataria if (!ref_freq) { 3032dbe06faSAlok Kataria ref_freq = freq->old; 3042dbe06faSAlok Kataria loops_per_jiffy_ref = *lpj; 3052dbe06faSAlok Kataria tsc_khz_ref = tsc_khz; 3062dbe06faSAlok Kataria } 3072dbe06faSAlok Kataria if ((val == CPUFREQ_PRECHANGE && freq->old < freq->new) || 3082dbe06faSAlok Kataria (val == CPUFREQ_POSTCHANGE && freq->old > freq->new) || 3092dbe06faSAlok Kataria (val == CPUFREQ_RESUMECHANGE)) { 3102dbe06faSAlok Kataria *lpj = cpufreq_scale(loops_per_jiffy_ref, ref_freq, freq->new); 3112dbe06faSAlok Kataria 3122dbe06faSAlok Kataria tsc_khz = cpufreq_scale(tsc_khz_ref, ref_freq, freq->new); 3132dbe06faSAlok Kataria if (!(freq->flags & CPUFREQ_CONST_LOOPS)) 3142dbe06faSAlok Kataria mark_tsc_unstable("cpufreq changes"); 3152dbe06faSAlok Kataria } 3162dbe06faSAlok Kataria 3172dbe06faSAlok Kataria set_cyc2ns_scale(tsc_khz_ref, freq->cpu); 3182dbe06faSAlok Kataria 3192dbe06faSAlok Kataria return 0; 3202dbe06faSAlok Kataria } 3212dbe06faSAlok Kataria 3222dbe06faSAlok Kataria static struct notifier_block time_cpufreq_notifier_block = { 3232dbe06faSAlok Kataria .notifier_call = time_cpufreq_notifier 3242dbe06faSAlok Kataria }; 3252dbe06faSAlok Kataria 3262dbe06faSAlok Kataria static int __init cpufreq_tsc(void) 3272dbe06faSAlok Kataria { 3282dbe06faSAlok Kataria cpufreq_register_notifier(&time_cpufreq_notifier_block, 3292dbe06faSAlok Kataria CPUFREQ_TRANSITION_NOTIFIER); 3302dbe06faSAlok Kataria return 0; 3312dbe06faSAlok Kataria } 3322dbe06faSAlok Kataria 3332dbe06faSAlok Kataria core_initcall(cpufreq_tsc); 3342dbe06faSAlok Kataria 3352dbe06faSAlok Kataria #endif /* CONFIG_CPU_FREQ */ 3368fbbc4b4SAlok Kataria 3378fbbc4b4SAlok Kataria /* clocksource code */ 3388fbbc4b4SAlok Kataria 3398fbbc4b4SAlok Kataria static struct clocksource clocksource_tsc; 3408fbbc4b4SAlok Kataria 3418fbbc4b4SAlok Kataria /* 3428fbbc4b4SAlok Kataria * We compare the TSC to the cycle_last value in the clocksource 3438fbbc4b4SAlok Kataria * structure to avoid a nasty time-warp. This can be observed in a 3448fbbc4b4SAlok Kataria * very small window right after one CPU updated cycle_last under 3458fbbc4b4SAlok Kataria * xtime/vsyscall_gtod lock and the other CPU reads a TSC value which 3468fbbc4b4SAlok Kataria * is smaller than the cycle_last reference value due to a TSC which 3478fbbc4b4SAlok Kataria * is slighty behind. This delta is nowhere else observable, but in 3488fbbc4b4SAlok Kataria * that case it results in a forward time jump in the range of hours 3498fbbc4b4SAlok Kataria * due to the unsigned delta calculation of the time keeping core 3508fbbc4b4SAlok Kataria * code, which is necessary to support wrapping clocksources like pm 3518fbbc4b4SAlok Kataria * timer. 3528fbbc4b4SAlok Kataria */ 3538fbbc4b4SAlok Kataria static cycle_t read_tsc(void) 3548fbbc4b4SAlok Kataria { 3558fbbc4b4SAlok Kataria cycle_t ret = (cycle_t)get_cycles(); 3568fbbc4b4SAlok Kataria 3578fbbc4b4SAlok Kataria return ret >= clocksource_tsc.cycle_last ? 3588fbbc4b4SAlok Kataria ret : clocksource_tsc.cycle_last; 3598fbbc4b4SAlok Kataria } 3608fbbc4b4SAlok Kataria 361431ceb83SThomas Gleixner #ifdef CONFIG_X86_64 3628fbbc4b4SAlok Kataria static cycle_t __vsyscall_fn vread_tsc(void) 3638fbbc4b4SAlok Kataria { 3648fbbc4b4SAlok Kataria cycle_t ret = (cycle_t)vget_cycles(); 3658fbbc4b4SAlok Kataria 3668fbbc4b4SAlok Kataria return ret >= __vsyscall_gtod_data.clock.cycle_last ? 3678fbbc4b4SAlok Kataria ret : __vsyscall_gtod_data.clock.cycle_last; 3688fbbc4b4SAlok Kataria } 369431ceb83SThomas Gleixner #endif 3708fbbc4b4SAlok Kataria 3718fbbc4b4SAlok Kataria static struct clocksource clocksource_tsc = { 3728fbbc4b4SAlok Kataria .name = "tsc", 3738fbbc4b4SAlok Kataria .rating = 300, 3748fbbc4b4SAlok Kataria .read = read_tsc, 3758fbbc4b4SAlok Kataria .mask = CLOCKSOURCE_MASK(64), 3768fbbc4b4SAlok Kataria .shift = 22, 3778fbbc4b4SAlok Kataria .flags = CLOCK_SOURCE_IS_CONTINUOUS | 3788fbbc4b4SAlok Kataria CLOCK_SOURCE_MUST_VERIFY, 3798fbbc4b4SAlok Kataria #ifdef CONFIG_X86_64 3808fbbc4b4SAlok Kataria .vread = vread_tsc, 3818fbbc4b4SAlok Kataria #endif 3828fbbc4b4SAlok Kataria }; 3838fbbc4b4SAlok Kataria 3848fbbc4b4SAlok Kataria void mark_tsc_unstable(char *reason) 3858fbbc4b4SAlok Kataria { 3868fbbc4b4SAlok Kataria if (!tsc_unstable) { 3878fbbc4b4SAlok Kataria tsc_unstable = 1; 3888fbbc4b4SAlok Kataria printk("Marking TSC unstable due to %s\n", reason); 3898fbbc4b4SAlok Kataria /* Change only the rating, when not registered */ 3908fbbc4b4SAlok Kataria if (clocksource_tsc.mult) 3918fbbc4b4SAlok Kataria clocksource_change_rating(&clocksource_tsc, 0); 3928fbbc4b4SAlok Kataria else 3938fbbc4b4SAlok Kataria clocksource_tsc.rating = 0; 3948fbbc4b4SAlok Kataria } 3958fbbc4b4SAlok Kataria } 3968fbbc4b4SAlok Kataria 3978fbbc4b4SAlok Kataria EXPORT_SYMBOL_GPL(mark_tsc_unstable); 3988fbbc4b4SAlok Kataria 3998fbbc4b4SAlok Kataria static int __init dmi_mark_tsc_unstable(const struct dmi_system_id *d) 4008fbbc4b4SAlok Kataria { 4018fbbc4b4SAlok Kataria printk(KERN_NOTICE "%s detected: marking TSC unstable.\n", 4028fbbc4b4SAlok Kataria d->ident); 4038fbbc4b4SAlok Kataria tsc_unstable = 1; 4048fbbc4b4SAlok Kataria return 0; 4058fbbc4b4SAlok Kataria } 4068fbbc4b4SAlok Kataria 4078fbbc4b4SAlok Kataria /* List of systems that have known TSC problems */ 4088fbbc4b4SAlok Kataria static struct dmi_system_id __initdata bad_tsc_dmi_table[] = { 4098fbbc4b4SAlok Kataria { 4108fbbc4b4SAlok Kataria .callback = dmi_mark_tsc_unstable, 4118fbbc4b4SAlok Kataria .ident = "IBM Thinkpad 380XD", 4128fbbc4b4SAlok Kataria .matches = { 4138fbbc4b4SAlok Kataria DMI_MATCH(DMI_BOARD_VENDOR, "IBM"), 4148fbbc4b4SAlok Kataria DMI_MATCH(DMI_BOARD_NAME, "2635FA0"), 4158fbbc4b4SAlok Kataria }, 4168fbbc4b4SAlok Kataria }, 4178fbbc4b4SAlok Kataria {} 4188fbbc4b4SAlok Kataria }; 4198fbbc4b4SAlok Kataria 4208fbbc4b4SAlok Kataria /* 4218fbbc4b4SAlok Kataria * Geode_LX - the OLPC CPU has a possibly a very reliable TSC 4228fbbc4b4SAlok Kataria */ 4238fbbc4b4SAlok Kataria #ifdef CONFIG_MGEODE_LX 4248fbbc4b4SAlok Kataria /* RTSC counts during suspend */ 4258fbbc4b4SAlok Kataria #define RTSC_SUSP 0x100 4268fbbc4b4SAlok Kataria 4278fbbc4b4SAlok Kataria static void __init check_geode_tsc_reliable(void) 4288fbbc4b4SAlok Kataria { 4298fbbc4b4SAlok Kataria unsigned long res_low, res_high; 4308fbbc4b4SAlok Kataria 4318fbbc4b4SAlok Kataria rdmsr_safe(MSR_GEODE_BUSCONT_CONF0, &res_low, &res_high); 4328fbbc4b4SAlok Kataria if (res_low & RTSC_SUSP) 4338fbbc4b4SAlok Kataria clocksource_tsc.flags &= ~CLOCK_SOURCE_MUST_VERIFY; 4348fbbc4b4SAlok Kataria } 4358fbbc4b4SAlok Kataria #else 4368fbbc4b4SAlok Kataria static inline void check_geode_tsc_reliable(void) { } 4378fbbc4b4SAlok Kataria #endif 4388fbbc4b4SAlok Kataria 4398fbbc4b4SAlok Kataria /* 4408fbbc4b4SAlok Kataria * Make an educated guess if the TSC is trustworthy and synchronized 4418fbbc4b4SAlok Kataria * over all CPUs. 4428fbbc4b4SAlok Kataria */ 4438fbbc4b4SAlok Kataria __cpuinit int unsynchronized_tsc(void) 4448fbbc4b4SAlok Kataria { 4458fbbc4b4SAlok Kataria if (!cpu_has_tsc || tsc_unstable) 4468fbbc4b4SAlok Kataria return 1; 4478fbbc4b4SAlok Kataria 4488fbbc4b4SAlok Kataria #ifdef CONFIG_SMP 4498fbbc4b4SAlok Kataria if (apic_is_clustered_box()) 4508fbbc4b4SAlok Kataria return 1; 4518fbbc4b4SAlok Kataria #endif 4528fbbc4b4SAlok Kataria 4538fbbc4b4SAlok Kataria if (boot_cpu_has(X86_FEATURE_CONSTANT_TSC)) 4548fbbc4b4SAlok Kataria return 0; 4558fbbc4b4SAlok Kataria /* 4568fbbc4b4SAlok Kataria * Intel systems are normally all synchronized. 4578fbbc4b4SAlok Kataria * Exceptions must mark TSC as unstable: 4588fbbc4b4SAlok Kataria */ 4598fbbc4b4SAlok Kataria if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL) { 4608fbbc4b4SAlok Kataria /* assume multi socket systems are not synchronized: */ 4618fbbc4b4SAlok Kataria if (num_possible_cpus() > 1) 4628fbbc4b4SAlok Kataria tsc_unstable = 1; 4638fbbc4b4SAlok Kataria } 4648fbbc4b4SAlok Kataria 4658fbbc4b4SAlok Kataria return tsc_unstable; 4668fbbc4b4SAlok Kataria } 4678fbbc4b4SAlok Kataria 4688fbbc4b4SAlok Kataria static void __init init_tsc_clocksource(void) 4698fbbc4b4SAlok Kataria { 4708fbbc4b4SAlok Kataria clocksource_tsc.mult = clocksource_khz2mult(tsc_khz, 4718fbbc4b4SAlok Kataria clocksource_tsc.shift); 4728fbbc4b4SAlok Kataria /* lower the rating if we already know its unstable: */ 4738fbbc4b4SAlok Kataria if (check_tsc_unstable()) { 4748fbbc4b4SAlok Kataria clocksource_tsc.rating = 0; 4758fbbc4b4SAlok Kataria clocksource_tsc.flags &= ~CLOCK_SOURCE_IS_CONTINUOUS; 4768fbbc4b4SAlok Kataria } 4778fbbc4b4SAlok Kataria clocksource_register(&clocksource_tsc); 4788fbbc4b4SAlok Kataria } 4798fbbc4b4SAlok Kataria 4808fbbc4b4SAlok Kataria void __init tsc_init(void) 4818fbbc4b4SAlok Kataria { 4828fbbc4b4SAlok Kataria u64 lpj; 4838fbbc4b4SAlok Kataria int cpu; 4848fbbc4b4SAlok Kataria 4858fbbc4b4SAlok Kataria if (!cpu_has_tsc) 4868fbbc4b4SAlok Kataria return; 4878fbbc4b4SAlok Kataria 488e93ef949SAlok Kataria tsc_khz = calibrate_tsc(); 489e93ef949SAlok Kataria cpu_khz = tsc_khz; 4908fbbc4b4SAlok Kataria 491e93ef949SAlok Kataria if (!tsc_khz) { 4928fbbc4b4SAlok Kataria mark_tsc_unstable("could not calculate TSC khz"); 4938fbbc4b4SAlok Kataria return; 4948fbbc4b4SAlok Kataria } 4958fbbc4b4SAlok Kataria 4968fbbc4b4SAlok Kataria #ifdef CONFIG_X86_64 4978fbbc4b4SAlok Kataria if (cpu_has(&boot_cpu_data, X86_FEATURE_CONSTANT_TSC) && 4988fbbc4b4SAlok Kataria (boot_cpu_data.x86_vendor == X86_VENDOR_AMD)) 4998fbbc4b4SAlok Kataria cpu_khz = calibrate_cpu(); 5008fbbc4b4SAlok Kataria #endif 5018fbbc4b4SAlok Kataria 5028fbbc4b4SAlok Kataria lpj = ((u64)tsc_khz * 1000); 5038fbbc4b4SAlok Kataria do_div(lpj, HZ); 5048fbbc4b4SAlok Kataria lpj_fine = lpj; 5058fbbc4b4SAlok Kataria 5068fbbc4b4SAlok Kataria printk("Detected %lu.%03lu MHz processor.\n", 5078fbbc4b4SAlok Kataria (unsigned long)cpu_khz / 1000, 5088fbbc4b4SAlok Kataria (unsigned long)cpu_khz % 1000); 5098fbbc4b4SAlok Kataria 5108fbbc4b4SAlok Kataria /* 5118fbbc4b4SAlok Kataria * Secondary CPUs do not run through tsc_init(), so set up 5128fbbc4b4SAlok Kataria * all the scale factors for all CPUs, assuming the same 5138fbbc4b4SAlok Kataria * speed as the bootup CPU. (cpufreq notifiers will fix this 5148fbbc4b4SAlok Kataria * up if their speed diverges) 5158fbbc4b4SAlok Kataria */ 5168fbbc4b4SAlok Kataria for_each_possible_cpu(cpu) 5178fbbc4b4SAlok Kataria set_cyc2ns_scale(cpu_khz, cpu); 5188fbbc4b4SAlok Kataria 5198fbbc4b4SAlok Kataria if (tsc_disabled > 0) 5208fbbc4b4SAlok Kataria return; 5218fbbc4b4SAlok Kataria 5228fbbc4b4SAlok Kataria /* now allow native_sched_clock() to use rdtsc */ 5238fbbc4b4SAlok Kataria tsc_disabled = 0; 5248fbbc4b4SAlok Kataria 5258fbbc4b4SAlok Kataria use_tsc_delay(); 5268fbbc4b4SAlok Kataria /* Check and install the TSC clocksource */ 5278fbbc4b4SAlok Kataria dmi_check_system(bad_tsc_dmi_table); 5288fbbc4b4SAlok Kataria 5298fbbc4b4SAlok Kataria if (unsynchronized_tsc()) 5308fbbc4b4SAlok Kataria mark_tsc_unstable("TSCs unsynchronized"); 5318fbbc4b4SAlok Kataria 5328fbbc4b4SAlok Kataria check_geode_tsc_reliable(); 5338fbbc4b4SAlok Kataria init_tsc_clocksource(); 5348fbbc4b4SAlok Kataria } 5358fbbc4b4SAlok Kataria 536