diff options
Diffstat (limited to 'drivers/acpi/processor_perflib.c')
-rw-r--r-- | drivers/acpi/processor_perflib.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c index a093dc163a42..836bfe069042 100644 --- a/drivers/acpi/processor_perflib.c +++ b/drivers/acpi/processor_perflib.c | |||
@@ -324,6 +324,34 @@ static int acpi_processor_get_performance_control(struct acpi_processor *pr) | |||
324 | return result; | 324 | return result; |
325 | } | 325 | } |
326 | 326 | ||
327 | #ifdef CONFIG_X86 | ||
328 | /* | ||
329 | * Some AMDs have 50MHz frequency multiples, but only provide 100MHz rounding | ||
330 | * in their ACPI data. Calculate the real values and fix up the _PSS data. | ||
331 | */ | ||
332 | static void amd_fixup_frequency(struct acpi_processor_px *px, int i) | ||
333 | { | ||
334 | u32 hi, lo, fid, did; | ||
335 | int index = px->control & 0x00000007; | ||
336 | |||
337 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) | ||
338 | return; | ||
339 | |||
340 | if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10) | ||
341 | || boot_cpu_data.x86 == 0x11) { | ||
342 | rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi); | ||
343 | fid = lo & 0x3f; | ||
344 | did = (lo >> 6) & 7; | ||
345 | if (boot_cpu_data.x86 == 0x10) | ||
346 | px->core_frequency = (100 * (fid + 0x10)) >> did; | ||
347 | else | ||
348 | px->core_frequency = (100 * (fid + 8)) >> did; | ||
349 | } | ||
350 | } | ||
351 | #else | ||
352 | static void amd_fixup_frequency(struct acpi_processor_px *px, int i) {}; | ||
353 | #endif | ||
354 | |||
327 | static int acpi_processor_get_performance_states(struct acpi_processor *pr) | 355 | static int acpi_processor_get_performance_states(struct acpi_processor *pr) |
328 | { | 356 | { |
329 | int result = 0; | 357 | int result = 0; |
@@ -379,6 +407,8 @@ static int acpi_processor_get_performance_states(struct acpi_processor *pr) | |||
379 | goto end; | 407 | goto end; |
380 | } | 408 | } |
381 | 409 | ||
410 | amd_fixup_frequency(px, i); | ||
411 | |||
382 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 412 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
383 | "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", | 413 | "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n", |
384 | i, | 414 | i, |