Commit 45738bdd authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: fix sched_clock, from Paul Mackerras:

From: Anton Blanchard <anton@samba.org>

Currently the sched_clock implementation for PPC64 is bogus.  It just reads
the timebase register, which counts at some fixed rate, typically around
100MHz.  This patch adds code to calculate a suitable multiplier from the
timebase frequency, and use that in sched_clock().
parent eabb2c77
......@@ -91,6 +91,9 @@ unsigned tb_to_us;
unsigned long processor_freq;
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
unsigned long tb_to_ns_scale;
unsigned long tb_to_ns_shift;
struct gettimeofday_struct do_gtod;
extern unsigned long wall_jiffies;
......@@ -313,11 +316,13 @@ int timer_interrupt(struct pt_regs * regs)
/*
* Scheduler clock - returns current time in nanosec units.
*
* This is wrong, but my CPUs run at 1GHz, so nyer nyer.
* Note: mulhdu(a, b) (multiply high double unsigned) returns
* the high 64 bits of a * b, i.e. (a * b) >> 64, where a and b
* are 64-bit unsigned numbers.
*/
unsigned long long sched_clock(void)
{
return get_tb();
return mulhdu(get_tb(), tb_to_ns_scale) << tb_to_ns_shift;
}
/*
......@@ -473,9 +478,30 @@ void __init time_init(void)
/* This function is only called on the boot processor */
unsigned long flags;
struct rtc_time tm;
struct div_result res;
unsigned long scale, shift;
ppc_md.calibrate_decr();
/*
* Compute scale factor for sched_clock.
* The calibrate_decr() function has set tb_ticks_per_sec,
* which is the timebase frequency.
* We compute 1e9 * 2^64 / tb_ticks_per_sec and interpret
* the 128-bit result as a 64.64 fixed-point number.
* We then shift that number right until it is less than 1.0,
* giving us the scale factor and shift count to use in
* sched_clock().
*/
div128_by_32(1000000000, 0, tb_ticks_per_sec, &res);
scale = res.result_low;
for (shift = 0; res.result_high != 0; ++shift) {
scale = (scale >> 1) | (res.result_high << 63);
res.result_high >>= 1;
}
tb_to_ns_scale = scale;
tb_to_ns_shift = shift;
#ifdef CONFIG_PPC_ISERIES
if (!piranha_simulator)
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment