View | Details | Raw Unified | Return to bug 3341 | Differences between
and this patch

Collapse All | Expand All

(-)2.6.15-rc2/arch/i386/kernel/apm.c (-2 / +3 lines)
Lines 230-235 Link Here
230
#include <asm/uaccess.h>
230
#include <asm/uaccess.h>
231
#include <asm/desc.h>
231
#include <asm/desc.h>
232
#include <asm/i8253.h>
232
#include <asm/i8253.h>
233
#include <asm/timer.h>
233
234
234
#include "io_ports.h"
235
#include "io_ports.h"
235
236
Lines 1188-1196 Link Here
1188
	/* set the clock to 100 Hz */
1189
	/* set the clock to 100 Hz */
1189
	outb_p(0x34, PIT_MODE);		/* binary, mode 2, LSB/MSB, ch 0 */
1190
	outb_p(0x34, PIT_MODE);		/* binary, mode 2, LSB/MSB, ch 0 */
1190
	udelay(10);
1191
	udelay(10);
1191
	outb_p(LATCH & 0xff, PIT_CH0);	/* LSB */
1192
	outb_p((LATCH * timer_mult / 1000) & 0xff, PIT_CH0);	/* LSB */
1192
	udelay(10);
1193
	udelay(10);
1193
	outb(LATCH >> 8, PIT_CH0);	/* MSB */
1194
	outb((LATCH * timer_mult / 1000) >> 8, PIT_CH0);	/* MSB */
1194
	udelay(10);
1195
	udelay(10);
1195
	spin_unlock_irqrestore(&i8253_lock, flags);
1196
	spin_unlock_irqrestore(&i8253_lock, flags);
1196
#endif
1197
#endif
(-)2.6.15-rc2/arch/i386/kernel/time.c (+6 lines)
Lines 82-87 Link Here
82
DEFINE_SPINLOCK(rtc_lock);
82
DEFINE_SPINLOCK(rtc_lock);
83
EXPORT_SYMBOL(rtc_lock);
83
EXPORT_SYMBOL(rtc_lock);
84
84
85
/* 
86
 * timer_mult is a mutiplier used to work around some very buggy
87
 * hardware where the PIT timer runs way too fast.
88
 */
89
u16 timer_mult = 1000;
90
85
#include <asm/i8253.h>
91
#include <asm/i8253.h>
86
92
87
DEFINE_SPINLOCK(i8253_lock);
93
DEFINE_SPINLOCK(i8253_lock);
(-)2.6.15-rc2/arch/i386/kernel/timers/common.c (-1 / +1 lines)
Lines 23-29 Link Here
23
 * device.
23
 * device.
24
 */
24
 */
25
25
26
#define CALIBRATE_TIME	(5 * 1000020/HZ)
26
#define CALIBRATE_TIME	(5 * 1000020/(HZ * timer_mult / 1000))
27
27
28
unsigned long calibrate_tsc(void)
28
unsigned long calibrate_tsc(void)
29
{
29
{
(-)2.6.15-rc2/arch/i386/kernel/timers/timer_pit.c (-4 / +4 lines)
Lines 116-123 Link Here
116
        /* VIA686a test code... reset the latch if count > max + 1 */
116
        /* VIA686a test code... reset the latch if count > max + 1 */
117
        if (count > LATCH) {
117
        if (count > LATCH) {
118
                outb_p(0x34, PIT_MODE);
118
                outb_p(0x34, PIT_MODE);
119
                outb_p(LATCH & 0xff, PIT_CH0);
119
                outb_p((LATCH * timer_mult / 1000) & 0xff, PIT_CH0);
120
                outb(LATCH >> 8, PIT_CH0);
120
                outb((LATCH * timer_mult / 1000) >> 8, PIT_CH0);
121
                count = LATCH - 1;
121
                count = LATCH - 1;
122
        }
122
        }
123
	
123
	
Lines 170-177 Link Here
170
	spin_lock_irqsave(&i8253_lock, flags);
170
	spin_lock_irqsave(&i8253_lock, flags);
171
	outb_p(0x34,PIT_MODE);		/* binary, mode 2, LSB/MSB, ch 0 */
171
	outb_p(0x34,PIT_MODE);		/* binary, mode 2, LSB/MSB, ch 0 */
172
	udelay(10);
172
	udelay(10);
173
	outb_p(LATCH & 0xff , PIT_CH0);	/* LSB */
173
	outb_p((LATCH * timer_mult / 1000) & 0xff , PIT_CH0);	/* LSB */
174
	udelay(10);
174
	udelay(10);
175
	outb(LATCH >> 8 , PIT_CH0);	/* MSB */
175
	outb((LATCH * timer_mult / 1000) >> 8 , PIT_CH0);	/* MSB */
176
	spin_unlock_irqrestore(&i8253_lock, flags);
176
	spin_unlock_irqrestore(&i8253_lock, flags);
177
}
177
}
(-)2.6.15-rc2/arch/i386/kernel/timers/timer_pm.c (-2 / +29 lines)
Lines 15-20 Link Here
15
#include <linux/module.h>
15
#include <linux/module.h>
16
#include <linux/device.h>
16
#include <linux/device.h>
17
#include <linux/init.h>
17
#include <linux/init.h>
18
#include <asm/delay.h>
18
#include <asm/types.h>
19
#include <asm/types.h>
19
#include <asm/timer.h>
20
#include <asm/timer.h>
20
#include <asm/smp.h>
21
#include <asm/smp.h>
Lines 23-28 Link Here
23
24
24
#include <linux/timex.h>
25
#include <linux/timex.h>
25
#include "mach_timer.h"
26
#include "mach_timer.h"
27
#include "io_ports.h"
26
28
27
/* Number of PMTMR ticks expected during calibration run */
29
/* Number of PMTMR ticks expected during calibration run */
28
#define PMTMR_TICKS_PER_SEC 3579545
30
#define PMTMR_TICKS_PER_SEC 3579545
Lines 35-40 Link Here
35
 * in arch/i386/acpi/boot.c */
37
 * in arch/i386/acpi/boot.c */
36
u32 pmtmr_ioport = 0;
38
u32 pmtmr_ioport = 0;
37
39
40
extern spinlock_t i8259A_lock;
41
extern spinlock_t i8253_lock;
38
42
39
/* value of the Power timer at last timer interrupt */
43
/* value of the Power timer at last timer interrupt */
40
static u32 offset_tick;
44
static u32 offset_tick;
Lines 66-76 Link Here
66
}
70
}
67
71
68
72
73
static void reinit_timer(void)
74
{
75
	unsigned long flags;
76
77
	spin_lock_irqsave(&i8253_lock, flags);
78
	outb_p(0x34, PIT_MODE);		/* binary, mode 2, LSB/MSB, ch 0 */
79
	udelay(10);
80
	outb_p((LATCH * timer_mult / 1000) & 0xff, PIT_CH0);	/* LSB */
81
	udelay(10);
82
	outb((LATCH * timer_mult / 1000) >> 8, PIT_CH0);	/* MSB */
83
	spin_unlock_irqrestore(&i8253_lock, flags);
84
}
85
69
/*
86
/*
70
 * Some boards have the PMTMR running way too fast. We check
87
 * Some boards have the PMTMR running way too fast. We check
71
 * the PMTMR rate against PIT channel 2 to catch these cases.
88
 * the PMTMR rate against PIT channel 2 to catch these cases.
72
 */
89
 */
73
static int verify_pmtmr_rate(void)
90
static int verify_pmtmr_rate(char* override)
74
{
91
{
75
	u32 value1, value2;
92
	u32 value1, value2;
76
	unsigned long count, delta;
93
	unsigned long count, delta;
Lines 81-89 Link Here
81
	value2 = read_pmtmr();
98
	value2 = read_pmtmr();
82
	delta = (value2 - value1) & ACPI_PM_MASK;
99
	delta = (value2 - value1) & ACPI_PM_MASK;
83
100
101
84
	/* Check that the PMTMR delta is within 5% of what we expect */
102
	/* Check that the PMTMR delta is within 5% of what we expect */
85
	if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
103
	if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
86
	    delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
104
	    delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
105
106
		timer_mult = PMTMR_EXPECTED_RATE * 1000 / delta;
107
		if (override[0]) {
108
			printk(KERN_INFO "PIT running at invalid rate, workaround multiplier set to %d.%d\n",  timer_mult / 1000, timer_mult % 1000);
109
			reinit_timer();
110
111
			return 0;
112
		}
113
87
		printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE);
114
		printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE);
88
		return -1;
115
		return -1;
89
	}
116
	}
Lines 124-130 Link Here
124
	return -ENODEV;
151
	return -ENODEV;
125
152
126
pm_good:
153
pm_good:
127
	if (verify_pmtmr_rate() != 0)
154
	if (verify_pmtmr_rate(override) != 0)
128
		return -ENODEV;
155
		return -ENODEV;
129
156
130
	init_cpu_khz();
157
	init_cpu_khz();
(-)2.6.15-rc2/arch/i386/kernel/timers/timer_tsc.c (-2 / +2 lines)
Lines 384-391 Link Here
384
	 */
384
	 */
385
	if (count > LATCH) {
385
	if (count > LATCH) {
386
		outb_p(0x34, PIT_MODE);
386
		outb_p(0x34, PIT_MODE);
387
		outb_p(LATCH & 0xff, PIT_CH0);
387
		outb_p((LATCH * timer_mult / 1000) & 0xff, PIT_CH0);
388
		outb(LATCH >> 8, PIT_CH0);
388
		outb((LATCH * timer_mult / 1000) >> 8, PIT_CH0);
389
		count = LATCH - 1;
389
		count = LATCH - 1;
390
	}
390
	}
391
391
(-)2.6.15-rc2/arch/x86_64/kernel/i8259.c (-2 / +3 lines)
Lines 18-23 Link Here
18
#include <asm/atomic.h>
18
#include <asm/atomic.h>
19
#include <asm/system.h>
19
#include <asm/system.h>
20
#include <asm/io.h>
20
#include <asm/io.h>
21
#include <asm/proto.h>
21
#include <asm/hw_irq.h>
22
#include <asm/hw_irq.h>
22
#include <asm/pgtable.h>
23
#include <asm/pgtable.h>
23
#include <asm/delay.h>
24
#include <asm/delay.h>
Lines 499-507 Link Here
499
{
500
{
500
	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
501
	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
501
	udelay(10);
502
	udelay(10);
502
	outb_p(LATCH & 0xff , 0x40);	/* LSB */
503
	outb_p((LATCH * timer_mult / 1000) & 0xff , 0x40);	/* LSB */
503
	udelay(10);
504
	udelay(10);
504
	outb(LATCH >> 8 , 0x40);	/* MSB */
505
	outb((LATCH * timer_mult / 1000) >> 8 , 0x40);		/* MSB */
505
}
506
}
506
507
507
static int timer_resume(struct sys_device *dev)
508
static int timer_resume(struct sys_device *dev)
(-)2.6.15-rc2/arch/x86_64/kernel/pmtimer.c (+43 lines)
Lines 35-40 Link Here
35
35
36
#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
36
#define ACPI_PM_MASK 0xFFFFFF /* limit it to 24 bits */
37
37
38
#define PMTMR_TICKS_PER_SEC 3579545
39
#define PMTMR_EXPECTED_RATE \
40
  ((LATCH * (PMTMR_TICKS_PER_SEC >> 10)) / (CLOCK_TICK_RATE>>10))
41
42
int verify_pmtmr_rate(int override)
43
{
44
	u32 value1, value2;
45
	unsigned long delta;
46
	unsigned long count = 0;
47
48
	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
49
	outb(0xb0, 0x43);
50
	outb_p(LATCH & 0xff, 0x42);
51
	outb_p(LATCH >> 8, 0x42);
52
53
	value1 = inl(pmtmr_ioport) & ACPI_PM_MASK;
54
55
	do {
56
		count++;
57
	} while ((inb_p(0x61) & 0x20) == 0);
58
59
	value2 = inl(pmtmr_ioport) & ACPI_PM_MASK;
60
	delta = (value2 - value1) & ACPI_PM_MASK;
61
62
	/* Check that the PMTMR delta is within 5% of what we expect */
63
	if (delta < (PMTMR_EXPECTED_RATE * 19) / 20 ||
64
	    delta > (PMTMR_EXPECTED_RATE * 21) / 20) {
65
66
		timer_mult = PMTMR_EXPECTED_RATE * 1000 / delta;
67
		if (override) {
68
			printk(KERN_INFO "PIT running at invalid rate, workaround multiplier set to %d.%d\n",  timer_mult / 1000, timer_mult % 1000);
69
			return 0;
70
		}
71
72
		printk(KERN_INFO "PM-Timer running at invalid rate: %lu%% of normal - aborting.\n", 100UL * delta / PMTMR_EXPECTED_RATE);
73
		return -1;
74
	}
75
76
	timer_mult = 1000;
77
	return 0;
78
}
79
80
38
static inline u32 cyc2us(u32 cycles)
81
static inline u32 cyc2us(u32 cycles)
39
{
82
{
40
	/* The Power Management Timer ticks at 3.579545 ticks per microsecond.
83
	/* The Power Management Timer ticks at 3.579545 ticks per microsecond.
(-)2.6.15-rc2/arch/x86_64/kernel/time.c (-5 / +30 lines)
Lines 42-47 Link Here
42
#include <asm/apic.h>
42
#include <asm/apic.h>
43
#endif
43
#endif
44
44
45
/* 
46
 * timer_mult is a mutiplier used to work around some very buggy
47
 * hardware where the PIT timer runs way too fast.
48
 */
49
u16 timer_mult = 1000;
50
45
#ifdef CONFIG_CPU_FREQ
51
#ifdef CONFIG_CPU_FREQ
46
static void cpufreq_delayed_get(void);
52
static void cpufreq_delayed_get(void);
47
#endif
53
#endif
Lines 53-58 Link Here
53
59
54
static int nohpet __initdata = 0;
60
static int nohpet __initdata = 0;
55
static int notsc __initdata = 0;
61
static int notsc __initdata = 0;
62
static int use_pmtimer __initdata = 0;
56
63
57
#undef HPET_HACK_ENABLE_DANGEROUS
64
#undef HPET_HACK_ENABLE_DANGEROUS
58
65
Lines 724-729 Link Here
724
	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
731
	outb((inb(0x61) & ~0x02) | 0x01, 0x61);
725
732
726
	outb(0xb0, 0x43);
733
	outb(0xb0, 0x43);
734
735
	/* 
736
	 * (PIT_TICK_RATE / (1000 / 50)) is 59659,
737
	 *  so we can't use the timer_mult here.
738
	 */
727
	outb((PIT_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
739
	outb((PIT_TICK_RATE / (1000 / 50)) & 0xff, 0x42);
728
	outb((PIT_TICK_RATE / (1000 / 50)) >> 8, 0x42);
740
	outb((PIT_TICK_RATE / (1000 / 50)) >> 8, 0x42);
729
	rdtscll(start);
741
	rdtscll(start);
Lines 734-740 Link Here
734
746
735
	spin_unlock_irqrestore(&i8253_lock, flags);
747
	spin_unlock_irqrestore(&i8253_lock, flags);
736
	
748
	
737
	return (end - start) / 50;
749
	/* 
750
	 * It's safer to use timer_mult on the
751
	 * computed value.
752
	 */
753
	return timer_mult * (end - start) / (50 * 1000);
738
}
754
}
739
755
740
#ifdef	CONFIG_HPET
756
#ifdef	CONFIG_HPET
Lines 863-870 Link Here
863
879
864
	spin_lock_irqsave(&i8253_lock, flags);
880
	spin_lock_irqsave(&i8253_lock, flags);
865
	outb_p(0x34, 0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
881
	outb_p(0x34, 0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
866
	outb_p(LATCH & 0xff, 0x40);	/* LSB */
882
	outb_p((LATCH * timer_mult / 1000) & 0xff, 0x40);	/* LSB */
867
	outb_p(LATCH >> 8, 0x40);	/* MSB */
883
	outb_p((LATCH * timer_mult / 1000) >> 8, 0x40);		/* MSB */
868
	spin_unlock_irqrestore(&i8253_lock, flags);
884
	spin_unlock_irqrestore(&i8253_lock, flags);
869
}
885
}
870
886
Lines 909-919 Link Here
909
                vxtime_hz = (1000000000000000L + hpet_period / 2) /
925
                vxtime_hz = (1000000000000000L + hpet_period / 2) /
910
			hpet_period;
926
			hpet_period;
911
927
912
	if (hpet_use_timer) {
928
	if (hpet_use_timer && !use_pmtimer) {
913
		cpu_khz = hpet_calibrate_tsc();
929
		cpu_khz = hpet_calibrate_tsc();
914
		timename = "HPET";
930
		timename = "HPET";
915
#ifdef CONFIG_X86_PM_TIMER
931
#ifdef CONFIG_X86_PM_TIMER
916
	} else if (pmtmr_ioport) {
932
	} else if ((pmtmr_ioport) && verify_pmtmr_rate(use_pmtimer)) {
917
		vxtime_hz = PM_TIMER_FREQUENCY;
933
		vxtime_hz = PM_TIMER_FREQUENCY;
918
		timename = "PM";
934
		timename = "PM";
919
		pit_init();
935
		pit_init();
Lines 1302-1305 Link Here
1302
1318
1303
__setup("notsc", notsc_setup);
1319
__setup("notsc", notsc_setup);
1304
1320
1321
static int __init pmtmr_setup(char *s)
1322
{
1323
	use_pmtimer = 1;
1324
	return 0;
1325
}
1326
1327
__setup("pmtmr", pmtmr_setup);
1328
1329
1305
1330
(-)2.6.15-rc2/Documentation/kernel-parameters.txt (+4 lines)
Lines 333-338 Link Here
333
			Forces specified timesource (if avaliable) to be used
333
			Forces specified timesource (if avaliable) to be used
334
			when calculating gettimeofday(). If specicified
334
			when calculating gettimeofday(). If specicified
335
			timesource is not avalible, it defaults to PIT.
335
			timesource is not avalible, it defaults to PIT.
336
 			When timesource is set to pmtmr manually, the PM timer is
337
 			assumed to be a reliable time source and the PIT/TSC is
338
 			adjusted accordingly. This can work around some very buggy 
339
 			hardware where the PIT timer runs way too fast.
336
			Format: { pit | tsc | cyclone | pmtmr }
340
			Format: { pit | tsc | cyclone | pmtmr }
337
341
338
	hpet=		[IA-32,HPET] option to disable HPET and use PIT.
342
	hpet=		[IA-32,HPET] option to disable HPET and use PIT.
(-)2.6.15-rc2/Documentation/x86_64/boot-options.txt (+6 lines)
Lines 61-66 Link Here
61
  This can be used to work around timing problems on multiprocessor systems
61
  This can be used to work around timing problems on multiprocessor systems
62
  with not properly synchronized CPUs.
62
  with not properly synchronized CPUs.
63
63
64
65
  pmtmr
66
  Assume the PM timer is a reliable time source and adjust the PIT/TSC accordingly.
67
  This can work around some very buggy hardware where the PIT timer runs way too
68
  fast.
69
64
  report_lost_ticks
70
  report_lost_ticks
65
  Report when timer interrupts are lost because some code turned off
71
  Report when timer interrupts are lost because some code turned off
66
  interrupts for too long.
72
  interrupts for too long.
(-)2.6.15-rc2/include/asm-i386/timer.h (+6 lines)
Lines 43-48 Link Here
43
43
44
extern int pit_latch_buggy;
44
extern int pit_latch_buggy;
45
45
46
/* 
47
 * timer_mult is a mutiplier used to work around some very buggy
48
 * hardware where the PIT timer runs way too fast.
49
 */
50
extern u16 timer_mult;
51
46
extern struct timer_opts *cur_timer;
52
extern struct timer_opts *cur_timer;
47
extern int timer_ack;
53
extern int timer_ack;
48
54
(-)2.6.15-rc2/include/asm-x86_64/proto.h (+2 lines)
Lines 42-47 Link Here
42
extern void time_init_gtod(void);
42
extern void time_init_gtod(void);
43
extern int pmtimer_mark_offset(void);
43
extern int pmtimer_mark_offset(void);
44
extern unsigned int do_gettimeoffset_pm(void);
44
extern unsigned int do_gettimeoffset_pm(void);
45
extern int verify_pmtmr_rate(int);
46
extern u16 timer_mult;
45
extern u32 pmtmr_ioport;
47
extern u32 pmtmr_ioport;
46
extern unsigned long long monotonic_base;
48
extern unsigned long long monotonic_base;
47
extern int sysctl_vsyscall;
49
extern int sysctl_vsyscall;

Return to bug 3341