diff options
Diffstat (limited to 'arch/x86/platform/mrst/mrst.c')
-rw-r--r-- | arch/x86/platform/mrst/mrst.c | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/arch/x86/platform/mrst/mrst.c b/arch/x86/platform/mrst/mrst.c index 541020df0da6..b1489a06a49d 100644 --- a/arch/x86/platform/mrst/mrst.c +++ b/arch/x86/platform/mrst/mrst.c | |||
@@ -187,11 +187,34 @@ int __init sfi_parse_mrtc(struct sfi_table_header *table) | |||
187 | static unsigned long __init mrst_calibrate_tsc(void) | 187 | static unsigned long __init mrst_calibrate_tsc(void) |
188 | { | 188 | { |
189 | unsigned long flags, fast_calibrate; | 189 | unsigned long flags, fast_calibrate; |
190 | 190 | if (__mrst_cpu_chip == MRST_CPU_CHIP_PENWELL) { | |
191 | local_irq_save(flags); | 191 | u32 lo, hi, ratio, fsb; |
192 | fast_calibrate = apbt_quick_calibrate(); | 192 | |
193 | local_irq_restore(flags); | 193 | rdmsr(MSR_IA32_PERF_STATUS, lo, hi); |
194 | 194 | pr_debug("IA32 perf status is 0x%x, 0x%0x\n", lo, hi); | |
195 | ratio = (hi >> 8) & 0x1f; | ||
196 | pr_debug("ratio is %d\n", ratio); | ||
197 | if (!ratio) { | ||
198 | pr_err("read a zero ratio, should be incorrect!\n"); | ||
199 | pr_err("force tsc ratio to 16 ...\n"); | ||
200 | ratio = 16; | ||
201 | } | ||
202 | rdmsr(MSR_FSB_FREQ, lo, hi); | ||
203 | if ((lo & 0x7) == 0x7) | ||
204 | fsb = PENWELL_FSB_FREQ_83SKU; | ||
205 | else | ||
206 | fsb = PENWELL_FSB_FREQ_100SKU; | ||
207 | fast_calibrate = ratio * fsb; | ||
208 | pr_debug("read penwell tsc %lu khz\n", fast_calibrate); | ||
209 | lapic_timer_frequency = fsb * 1000 / HZ; | ||
210 | /* mark tsc clocksource as reliable */ | ||
211 | set_cpu_cap(&boot_cpu_data, X86_FEATURE_TSC_RELIABLE); | ||
212 | } else { | ||
213 | local_irq_save(flags); | ||
214 | fast_calibrate = apbt_quick_calibrate(); | ||
215 | local_irq_restore(flags); | ||
216 | } | ||
217 | |||
195 | if (fast_calibrate) | 218 | if (fast_calibrate) |
196 | return fast_calibrate; | 219 | return fast_calibrate; |
197 | 220 | ||
@@ -254,6 +277,17 @@ static void mrst_reboot(void) | |||
254 | } | 277 | } |
255 | 278 | ||
256 | /* | 279 | /* |
280 | * Moorestown does not have external NMI source nor port 0x61 to report | ||
281 | * NMI status. The possible NMI sources are from pmu as a result of NMI | ||
282 | * watchdog or lock debug. Reading io port 0x61 results in 0xff which | ||
283 | * misled NMI handler. | ||
284 | */ | ||
285 | static unsigned char mrst_get_nmi_reason(void) | ||
286 | { | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | /* | ||
257 | * Moorestown specific x86_init function overrides and early setup | 291 | * Moorestown specific x86_init function overrides and early setup |
258 | * calls. | 292 | * calls. |
259 | */ | 293 | */ |
@@ -274,6 +308,8 @@ void __init x86_mrst_early_setup(void) | |||
274 | x86_platform.calibrate_tsc = mrst_calibrate_tsc; | 308 | x86_platform.calibrate_tsc = mrst_calibrate_tsc; |
275 | x86_platform.i8042_detect = mrst_i8042_detect; | 309 | x86_platform.i8042_detect = mrst_i8042_detect; |
276 | x86_init.timers.wallclock_init = mrst_rtc_init; | 310 | x86_init.timers.wallclock_init = mrst_rtc_init; |
311 | x86_platform.get_nmi_reason = mrst_get_nmi_reason; | ||
312 | |||
277 | x86_init.pci.init = pci_mrst_init; | 313 | x86_init.pci.init = pci_mrst_init; |
278 | x86_init.pci.fixup_irqs = x86_init_noop; | 314 | x86_init.pci.fixup_irqs = x86_init_noop; |
279 | 315 | ||