aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-06-19 21:51:21 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-06-19 21:51:21 -0400
commitbbf70132db2767f66b411fa90488aacac72e06dd (patch)
tree19bebd76503c351f74e2fc24ac161b20c8d30fd4 /arch/i386
parent2090af718014f3d434fb8b85b00eeea01ebcec19 (diff)
parent6ccf58ab22499139bacc683493c9fd70af55adbb (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq
* master.kernel.org:/pub/scm/linux/kernel/git/davej/cpufreq: [CPUFREQ] sets nforce2 minimum PLL divider to 2. [CPUFREQ] Make powernow-k7 work on SMP kernels. [CPUFREQ] cpufreq core {d,}printk adjustments [CPUFREQ] dprintk adjustments to cpufreq-speedstep-centrino [CPUFREQ] dprintk adjustments to cpufreq-nforce2 [CPUFREQ] Prepare powernow-k8 for future CPUs. [CPUFREQ] Make acpi-cpufreq 'sticky'. [CPUFREQ] Remove strange No-op from longrun.c [CPUFREQ] Remove more freq_table reinitialisations. [CPUFREQ] Fix another redundant initialisation in freq_table [CPUFREQ] Remove duplicate assignment in freq_table [CPUFREQ] CodingStyle nits in cpufreq_stats.c [CPUFREQ] Remove duplicate assignment from cpufreq-nforce2 [CPUFREQ] Remove pointless reinitialisations in acpi-cpufreq [CPUFREQ] Remove pointless reinitialisation from powernow-k8 [CPUFREQ] Remove redundant initialisation from longhaul. [CPUFREQ] Clean up longhaul's speed pretty-printer [CPUFREQ] Disambiguate loop indexes in powernow-k7 [CPUFREQ] Typo in powernow-k8
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c20
-rw-r--r--arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c11
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longhaul.c20
-rw-r--r--arch/i386/kernel/cpu/cpufreq/longrun.c1
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k7.c13
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.c344
-rw-r--r--arch/i386/kernel/cpu/cpufreq/powernow-k8.h40
-rw-r--r--arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c12
8 files changed, 331 insertions, 130 deletions
diff --git a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
index 3852d0a4c1b5..1a7bdcef1926 100644
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -104,7 +104,7 @@ acpi_processor_set_performance (
104{ 104{
105 u16 port = 0; 105 u16 port = 0;
106 u8 bit_width = 0; 106 u8 bit_width = 0;
107 int ret = 0; 107 int ret;
108 u32 value = 0; 108 u32 value = 0;
109 int i = 0; 109 int i = 0;
110 struct cpufreq_freqs cpufreq_freqs; 110 struct cpufreq_freqs cpufreq_freqs;
@@ -195,7 +195,6 @@ acpi_processor_set_performance (
195 udelay(10); 195 udelay(10);
196 } 196 }
197 } else { 197 } else {
198 i = 0;
199 value = (u32) data->acpi_data.states[state].status; 198 value = (u32) data->acpi_data.states[state].status;
200 } 199 }
201 200
@@ -444,14 +443,15 @@ static struct freq_attr* acpi_cpufreq_attr[] = {
444}; 443};
445 444
446static struct cpufreq_driver acpi_cpufreq_driver = { 445static struct cpufreq_driver acpi_cpufreq_driver = {
447 .verify = acpi_cpufreq_verify, 446 .verify = acpi_cpufreq_verify,
448 .target = acpi_cpufreq_target, 447 .target = acpi_cpufreq_target,
449 .init = acpi_cpufreq_cpu_init, 448 .init = acpi_cpufreq_cpu_init,
450 .exit = acpi_cpufreq_cpu_exit, 449 .exit = acpi_cpufreq_cpu_exit,
451 .resume = acpi_cpufreq_resume, 450 .resume = acpi_cpufreq_resume,
452 .name = "acpi-cpufreq", 451 .name = "acpi-cpufreq",
453 .owner = THIS_MODULE, 452 .owner = THIS_MODULE,
454 .attr = acpi_cpufreq_attr, 453 .attr = acpi_cpufreq_attr,
454 .flags = CPUFREQ_STICKY,
455}; 455};
456 456
457 457
diff --git a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
index f275e0d4aee5..0d49d73d1b71 100644
--- a/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
+++ b/arch/i386/kernel/cpu/cpufreq/cpufreq-nforce2.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * (C) 2004 Sebastian Witt <se.witt@gmx.net> 2 * (C) 2004-2006 Sebastian Witt <se.witt@gmx.net>
3 * 3 *
4 * Licensed under the terms of the GNU GPL License version 2. 4 * Licensed under the terms of the GNU GPL License version 2.
5 * Based upon reverse engineered information 5 * Based upon reverse engineered information
@@ -90,7 +90,7 @@ static int nforce2_calc_pll(unsigned int fsb)
90 90
91 /* Try to calculate multiplier and divider up to 4 times */ 91 /* Try to calculate multiplier and divider up to 4 times */
92 while (((mul == 0) || (div == 0)) && (tried <= 3)) { 92 while (((mul == 0) || (div == 0)) && (tried <= 3)) {
93 for (xdiv = 1; xdiv <= 0x80; xdiv++) 93 for (xdiv = 2; xdiv <= 0x80; xdiv++)
94 for (xmul = 1; xmul <= 0xfe; xmul++) 94 for (xmul = 1; xmul <= 0xfe; xmul++)
95 if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) == 95 if (nforce2_calc_fsb(NFORCE2_PLL(xmul, xdiv)) ==
96 fsb + tried) { 96 fsb + tried) {
@@ -117,8 +117,7 @@ static void nforce2_write_pll(int pll)
117 int temp; 117 int temp;
118 118
119 /* Set the pll addr. to 0x00 */ 119 /* Set the pll addr. to 0x00 */
120 temp = 0x00; 120 pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, 0);
121 pci_write_config_dword(nforce2_chipset_dev, NFORCE2_PLLADR, temp);
122 121
123 /* Now write the value in all 64 registers */ 122 /* Now write the value in all 64 registers */
124 for (temp = 0; temp <= 0x3f; temp++) 123 for (temp = 0; temp <= 0x3f; temp++)
@@ -266,7 +265,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
266 if (freqs.old == freqs.new) 265 if (freqs.old == freqs.new)
267 return 0; 266 return 0;
268 267
269 dprintk(KERN_INFO "cpufreq: Old CPU frequency %d kHz, new %d kHz\n", 268 dprintk("Old CPU frequency %d kHz, new %d kHz\n",
270 freqs.old, freqs.new); 269 freqs.old, freqs.new);
271 270
272 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 271 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
@@ -278,7 +277,7 @@ static int nforce2_target(struct cpufreq_policy *policy,
278 printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n", 277 printk(KERN_ERR "cpufreq: Changing FSB to %d failed\n",
279 target_fsb); 278 target_fsb);
280 else 279 else
281 dprintk(KERN_INFO "cpufreq: Changed FSB successfully to %d\n", 280 dprintk("Changed FSB successfully to %d\n",
282 target_fsb); 281 target_fsb);
283 282
284 /* Enable IRQs */ 283 /* Enable IRQs */
diff --git a/arch/i386/kernel/cpu/cpufreq/longhaul.c b/arch/i386/kernel/cpu/cpufreq/longhaul.c
index 8ef38544453c..146f607e9c44 100644
--- a/arch/i386/kernel/cpu/cpufreq/longhaul.c
+++ b/arch/i386/kernel/cpu/cpufreq/longhaul.c
@@ -77,13 +77,17 @@ static char speedbuffer[8];
77 77
78static char *print_speed(int speed) 78static char *print_speed(int speed)
79{ 79{
80 if (speed > 1000) { 80 if (speed < 1000) {
81 if (speed%1000 == 0) 81 snprintf(speedbuffer, sizeof(speedbuffer),"%dMHz", speed);
82 sprintf (speedbuffer, "%dGHz", speed/1000); 82 return speedbuffer;
83 else 83 }
84 sprintf (speedbuffer, "%d.%dGHz", speed/1000, (speed%1000)/100); 84
85 } else 85 if (speed%1000 == 0)
86 sprintf (speedbuffer, "%dMHz", speed); 86 snprintf(speedbuffer, sizeof(speedbuffer),
87 "%dGHz", speed/1000);
88 else
89 snprintf(speedbuffer, sizeof(speedbuffer),
90 "%d.%dGHz", speed/1000, (speed%1000)/100);
87 91
88 return speedbuffer; 92 return speedbuffer;
89} 93}
@@ -675,7 +679,7 @@ static int __init longhaul_init(void)
675 679
676static void __exit longhaul_exit(void) 680static void __exit longhaul_exit(void)
677{ 681{
678 int i=0; 682 int i;
679 683
680 for (i=0; i < numscales; i++) { 684 for (i=0; i < numscales; i++) {
681 if (clock_ratio[i] == maxmult) { 685 if (clock_ratio[i] == maxmult) {
diff --git a/arch/i386/kernel/cpu/cpufreq/longrun.c b/arch/i386/kernel/cpu/cpufreq/longrun.c
index e3868de4dc2e..b2689514295a 100644
--- a/arch/i386/kernel/cpu/cpufreq/longrun.c
+++ b/arch/i386/kernel/cpu/cpufreq/longrun.c
@@ -223,7 +223,6 @@ static unsigned int __init longrun_determine_freqs(unsigned int *low_freq,
223 /* set to 0 to try_hi perf_pctg */ 223 /* set to 0 to try_hi perf_pctg */
224 msr_lo &= 0xFFFFFF80; 224 msr_lo &= 0xFFFFFF80;
225 msr_hi &= 0xFFFFFF80; 225 msr_hi &= 0xFFFFFF80;
226 msr_lo |= 0;
227 msr_hi |= try_hi; 226 msr_hi |= try_hi;
228 wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi); 227 wrmsr(MSR_TMTA_LONGRUN_CTRL, msr_lo, msr_hi);
229 228
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
index 2bf4237cb94e..694d4793bf6a 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k7.c
@@ -452,23 +452,23 @@ static int powernow_decode_bios (int maxfid, int startvid)
452 452
453 pst = (struct pst_s *) p; 453 pst = (struct pst_s *) p;
454 454
455 for (i = 0 ; i <psb->numpst; i++) { 455 for (j=0; j<psb->numpst; j++) {
456 pst = (struct pst_s *) p; 456 pst = (struct pst_s *) p;
457 number_scales = pst->numpstates; 457 number_scales = pst->numpstates;
458 458
459 if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) && 459 if ((etuple == pst->cpuid) && check_fsb(pst->fsbspeed) &&
460 (maxfid==pst->maxfid) && (startvid==pst->startvid)) 460 (maxfid==pst->maxfid) && (startvid==pst->startvid))
461 { 461 {
462 dprintk ("PST:%d (@%p)\n", i, pst); 462 dprintk ("PST:%d (@%p)\n", j, pst);
463 dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n", 463 dprintk (" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n",
464 pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid); 464 pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
465 465
466 ret = get_ranges ((char *) pst + sizeof (struct pst_s)); 466 ret = get_ranges ((char *) pst + sizeof (struct pst_s));
467 return ret; 467 return ret;
468
469 } else { 468 } else {
469 unsigned int k;
470 p = (char *) pst + sizeof (struct pst_s); 470 p = (char *) pst + sizeof (struct pst_s);
471 for (j=0 ; j < number_scales; j++) 471 for (k=0; k<number_scales; k++)
472 p+=2; 472 p+=2;
473 } 473 }
474 } 474 }
@@ -581,10 +581,7 @@ static int __init powernow_cpu_init (struct cpufreq_policy *policy)
581 581
582 rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val); 582 rdmsrl (MSR_K7_FID_VID_STATUS, fidvidstatus.val);
583 583
584 /* recalibrate cpu_khz */ 584 recalibrate_cpu_khz();
585 result = recalibrate_cpu_khz();
586 if (result)
587 return result;
588 585
589 fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID]; 586 fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
590 if (!fsb) { 587 if (!fsb) {
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
index 71fffa174425..b4277f58f40c 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. 2 * (c) 2003-2006 Advanced Micro Devices, Inc.
3 * Your use of this code is subject to the terms and conditions of the 3 * Your use of this code is subject to the terms and conditions of the
4 * GNU general public license version 2. See "COPYING" or 4 * GNU general public license version 2. See "COPYING" or
5 * http://www.gnu.org/licenses/gpl.html 5 * http://www.gnu.org/licenses/gpl.html
@@ -14,13 +14,13 @@
14 * Based upon datasheets & sample CPUs kindly provided by AMD. 14 * Based upon datasheets & sample CPUs kindly provided by AMD.
15 * 15 *
16 * Valuable input gratefully received from Dave Jones, Pavel Machek, 16 * Valuable input gratefully received from Dave Jones, Pavel Machek,
17 * Dominik Brodowski, and others. 17 * Dominik Brodowski, Jacob Shin, and others.
18 * Originally developed by Paul Devriendt. 18 * Originally developed by Paul Devriendt.
19 * Processor information obtained from Chapter 9 (Power and Thermal Management) 19 * Processor information obtained from Chapter 9 (Power and Thermal Management)
20 * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD 20 * of the "BIOS and Kernel Developer's Guide for the AMD Athlon 64 and AMD
21 * Opteron Processors" available for download from www.amd.com 21 * Opteron Processors" available for download from www.amd.com
22 * 22 *
23 * Tables for specific CPUs can be infrerred from 23 * Tables for specific CPUs can be inferred from
24 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf 24 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/30430.pdf
25 */ 25 */
26 26
@@ -46,7 +46,7 @@
46 46
47#define PFX "powernow-k8: " 47#define PFX "powernow-k8: "
48#define BFX PFX "BIOS error: " 48#define BFX PFX "BIOS error: "
49#define VERSION "version 1.60.2" 49#define VERSION "version 2.00.00"
50#include "powernow-k8.h" 50#include "powernow-k8.h"
51 51
52/* serialize freq changes */ 52/* serialize freq changes */
@@ -54,6 +54,8 @@ static DEFINE_MUTEX(fidvid_mutex);
54 54
55static struct powernow_k8_data *powernow_data[NR_CPUS]; 55static struct powernow_k8_data *powernow_data[NR_CPUS];
56 56
57static int cpu_family = CPU_OPTERON;
58
57#ifndef CONFIG_SMP 59#ifndef CONFIG_SMP
58static cpumask_t cpu_core_map[1]; 60static cpumask_t cpu_core_map[1];
59#endif 61#endif
@@ -64,16 +66,36 @@ static u32 find_freq_from_fid(u32 fid)
64 return 800 + (fid * 100); 66 return 800 + (fid * 100);
65} 67}
66 68
69
67/* Return a frequency in KHz, given an input fid */ 70/* Return a frequency in KHz, given an input fid */
68static u32 find_khz_freq_from_fid(u32 fid) 71static u32 find_khz_freq_from_fid(u32 fid)
69{ 72{
70 return 1000 * find_freq_from_fid(fid); 73 return 1000 * find_freq_from_fid(fid);
71} 74}
72 75
73/* Return a voltage in miliVolts, given an input vid */ 76/* Return a frequency in MHz, given an input fid and did */
74static u32 find_millivolts_from_vid(struct powernow_k8_data *data, u32 vid) 77static u32 find_freq_from_fiddid(u32 fid, u32 did)
78{
79 return 100 * (fid + 0x10) >> did;
80}
81
82static u32 find_khz_freq_from_fiddid(u32 fid, u32 did)
75{ 83{
76 return 1550-vid*25; 84 return 1000 * find_freq_from_fiddid(fid, did);
85}
86
87static u32 find_fid_from_pstate(u32 pstate)
88{
89 u32 hi, lo;
90 rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
91 return lo & HW_PSTATE_FID_MASK;
92}
93
94static u32 find_did_from_pstate(u32 pstate)
95{
96 u32 hi, lo;
97 rdmsr(MSR_PSTATE_DEF_BASE + pstate, lo, hi);
98 return (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
77} 99}
78 100
79/* Return the vco fid for an input fid 101/* Return the vco fid for an input fid
@@ -98,6 +120,9 @@ static int pending_bit_stuck(void)
98{ 120{
99 u32 lo, hi; 121 u32 lo, hi;
100 122
123 if (cpu_family)
124 return 0;
125
101 rdmsr(MSR_FIDVID_STATUS, lo, hi); 126 rdmsr(MSR_FIDVID_STATUS, lo, hi);
102 return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0; 127 return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
103} 128}
@@ -111,6 +136,14 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
111 u32 lo, hi; 136 u32 lo, hi;
112 u32 i = 0; 137 u32 i = 0;
113 138
139 if (cpu_family) {
140 rdmsr(MSR_PSTATE_STATUS, lo, hi);
141 i = lo & HW_PSTATE_MASK;
142 rdmsr(MSR_PSTATE_DEF_BASE + i, lo, hi);
143 data->currfid = lo & HW_PSTATE_FID_MASK;
144 data->currdid = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
145 return 0;
146 }
114 do { 147 do {
115 if (i++ > 10000) { 148 if (i++ > 10000) {
116 dprintk("detected change pending stuck\n"); 149 dprintk("detected change pending stuck\n");
@@ -175,7 +208,7 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid)
175 do { 208 do {
176 wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); 209 wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION);
177 if (i++ > 100) { 210 if (i++ > 100) {
178 printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); 211 printk(KERN_ERR PFX "Hardware error - pending bit very stuck - no further pstate changes possible\n");
179 return 1; 212 return 1;
180 } 213 }
181 } while (query_current_values_with_pending_wait(data)); 214 } while (query_current_values_with_pending_wait(data));
@@ -255,7 +288,15 @@ static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid,
255 return 0; 288 return 0;
256} 289}
257 290
258/* Change the fid and vid, by the 3 phases. */ 291/* Change hardware pstate by single MSR write */
292static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
293{
294 wrmsr(MSR_PSTATE_CTRL, pstate, 0);
295 data->currfid = find_fid_from_pstate(pstate);
296 return 0;
297}
298
299/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
259static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 reqvid) 300static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 reqvid)
260{ 301{
261 if (core_voltage_pre_transition(data, reqvid)) 302 if (core_voltage_pre_transition(data, reqvid))
@@ -474,26 +515,35 @@ static int check_supported_cpu(unsigned int cpu)
474 goto out; 515 goto out;
475 516
476 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); 517 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE);
477 if ((eax & CPUID_XFAM) != CPUID_XFAM_K8) 518 if (((eax & CPUID_XFAM) != CPUID_XFAM_K8) &&
519 ((eax & CPUID_XFAM) < CPUID_XFAM_10H))
478 goto out; 520 goto out;
479 521
480 if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || 522 if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) {
481 ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) { 523 if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) ||
482 printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); 524 ((eax & CPUID_XMOD) > CPUID_XMOD_REV_G)) {
483 goto out; 525 printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax);
484 } 526 goto out;
527 }
485 528
486 eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES); 529 eax = cpuid_eax(CPUID_GET_MAX_CAPABILITIES);
487 if (eax < CPUID_FREQ_VOLT_CAPABILITIES) { 530 if (eax < CPUID_FREQ_VOLT_CAPABILITIES) {
488 printk(KERN_INFO PFX 531 printk(KERN_INFO PFX
489 "No frequency change capabilities detected\n"); 532 "No frequency change capabilities detected\n");
490 goto out; 533 goto out;
491 } 534 }
492 535
493 cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); 536 cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
494 if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) { 537 if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) {
495 printk(KERN_INFO PFX "Power state transitions not supported\n"); 538 printk(KERN_INFO PFX "Power state transitions not supported\n");
496 goto out; 539 goto out;
540 }
541 } else { /* must be a HW Pstate capable processor */
542 cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
543 if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE)
544 cpu_family = CPU_HW_PSTATE;
545 else
546 goto out;
497 } 547 }
498 548
499 rc = 1; 549 rc = 1;
@@ -547,12 +597,18 @@ static void print_basics(struct powernow_k8_data *data)
547{ 597{
548 int j; 598 int j;
549 for (j = 0; j < data->numps; j++) { 599 for (j = 0; j < data->numps; j++) {
550 if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) 600 if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) {
551 printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x (%d mV)\n", j, 601 if (cpu_family) {
602 printk(KERN_INFO PFX " %d : fid 0x%x gid 0x%x (%d MHz)\n", j, (data->powernow_table[j].index & 0xff00) >> 8,
603 (data->powernow_table[j].index & 0xff0000) >> 16,
604 data->powernow_table[j].frequency/1000);
605 } else {
606 printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", j,
552 data->powernow_table[j].index & 0xff, 607 data->powernow_table[j].index & 0xff,
553 data->powernow_table[j].frequency/1000, 608 data->powernow_table[j].frequency/1000,
554 data->powernow_table[j].index >> 8, 609 data->powernow_table[j].index >> 8);
555 find_millivolts_from_vid(data, data->powernow_table[j].index >> 8)); 610 }
611 }
556 } 612 }
557 if (data->batps) 613 if (data->batps)
558 printk(KERN_INFO PFX "Only %d pstates on battery\n", data->batps); 614 printk(KERN_INFO PFX "Only %d pstates on battery\n", data->batps);
@@ -702,7 +758,7 @@ static int find_psb_table(struct powernow_k8_data *data)
702#ifdef CONFIG_X86_POWERNOW_K8_ACPI 758#ifdef CONFIG_X86_POWERNOW_K8_ACPI
703static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) 759static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index)
704{ 760{
705 if (!data->acpi_data.state_count) 761 if (!data->acpi_data.state_count || cpu_family)
706 return; 762 return;
707 763
708 data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; 764 data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK;
@@ -715,9 +771,8 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned
715 771
716static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) 772static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
717{ 773{
718 int i;
719 int cntlofreq = 0;
720 struct cpufreq_frequency_table *powernow_table; 774 struct cpufreq_frequency_table *powernow_table;
775 int ret_val;
721 776
722 if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { 777 if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) {
723 dprintk("register performance failed: bad ACPI data\n"); 778 dprintk("register performance failed: bad ACPI data\n");
@@ -746,6 +801,85 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
746 goto err_out; 801 goto err_out;
747 } 802 }
748 803
804 if (cpu_family)
805 ret_val = fill_powernow_table_pstate(data, powernow_table);
806 else
807 ret_val = fill_powernow_table_fidvid(data, powernow_table);
808 if (ret_val)
809 goto err_out_mem;
810
811 powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END;
812 powernow_table[data->acpi_data.state_count].index = 0;
813 data->powernow_table = powernow_table;
814
815 /* fill in data */
816 data->numps = data->acpi_data.state_count;
817 print_basics(data);
818 powernow_k8_acpi_pst_values(data, 0);
819
820 /* notify BIOS that we exist */
821 acpi_processor_notify_smm(THIS_MODULE);
822
823 return 0;
824
825err_out_mem:
826 kfree(powernow_table);
827
828err_out:
829 acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
830
831 /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */
832 data->acpi_data.state_count = 0;
833
834 return -ENODEV;
835}
836
837static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
838{
839 int i;
840
841 for (i = 0; i < data->acpi_data.state_count; i++) {
842 u32 index;
843 u32 hi = 0, lo = 0;
844 u32 fid;
845 u32 did;
846
847 index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
848 if (index > MAX_HW_PSTATE) {
849 printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index);
850 printk(KERN_ERR PFX "Please report to BIOS manufacturer\n");
851 }
852 rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
853 if (!(hi & HW_PSTATE_VALID_MASK)) {
854 dprintk("invalid pstate %d, ignoring\n", index);
855 powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
856 continue;
857 }
858
859 fid = lo & HW_PSTATE_FID_MASK;
860 did = (lo & HW_PSTATE_DID_MASK) >> HW_PSTATE_DID_SHIFT;
861
862 dprintk(" %d : fid 0x%x, did 0x%x\n", index, fid, did);
863
864 powernow_table[i].index = index | (fid << HW_FID_INDEX_SHIFT) | (did << HW_DID_INDEX_SHIFT);
865
866 powernow_table[i].frequency = find_khz_freq_from_fiddid(fid, did);
867
868 if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) {
869 printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n",
870 powernow_table[i].frequency,
871 (unsigned int) (data->acpi_data.states[i].core_frequency * 1000));
872 powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID;
873 continue;
874 }
875 }
876 return 0;
877}
878
879static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table)
880{
881 int i;
882 int cntlofreq = 0;
749 for (i = 0; i < data->acpi_data.state_count; i++) { 883 for (i = 0; i < data->acpi_data.state_count; i++) {
750 u32 fid; 884 u32 fid;
751 u32 vid; 885 u32 vid;
@@ -786,7 +920,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
786 if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || 920 if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) ||
787 (powernow_table[i].index != powernow_table[cntlofreq].index)) { 921 (powernow_table[i].index != powernow_table[cntlofreq].index)) {
788 printk(KERN_ERR PFX "Too many lo freq table entries\n"); 922 printk(KERN_ERR PFX "Too many lo freq table entries\n");
789 goto err_out_mem; 923 return 1;
790 } 924 }
791 925
792 dprintk("double low frequency table entry, ignoring it.\n"); 926 dprintk("double low frequency table entry, ignoring it.\n");
@@ -804,31 +938,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
804 continue; 938 continue;
805 } 939 }
806 } 940 }
807
808 powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END;
809 powernow_table[data->acpi_data.state_count].index = 0;
810 data->powernow_table = powernow_table;
811
812 /* fill in data */
813 data->numps = data->acpi_data.state_count;
814 print_basics(data);
815 powernow_k8_acpi_pst_values(data, 0);
816
817 /* notify BIOS that we exist */
818 acpi_processor_notify_smm(THIS_MODULE);
819
820 return 0; 941 return 0;
821
822err_out_mem:
823 kfree(powernow_table);
824
825err_out:
826 acpi_processor_unregister_performance(&data->acpi_data, data->cpu);
827
828 /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */
829 data->acpi_data.state_count = 0;
830
831 return -ENODEV;
832} 942}
833 943
834static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) 944static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data)
@@ -844,20 +954,20 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned
844#endif /* CONFIG_X86_POWERNOW_K8_ACPI */ 954#endif /* CONFIG_X86_POWERNOW_K8_ACPI */
845 955
846/* Take a frequency, and issue the fid/vid transition command */ 956/* Take a frequency, and issue the fid/vid transition command */
847static int transition_frequency(struct powernow_k8_data *data, unsigned int index) 957static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned int index)
848{ 958{
849 u32 fid; 959 u32 fid = 0;
850 u32 vid; 960 u32 vid = 0;
851 int res, i; 961 int res, i;
852 struct cpufreq_freqs freqs; 962 struct cpufreq_freqs freqs;
853 963
854 dprintk("cpu %d transition to index %u\n", smp_processor_id(), index); 964 dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
855 965
966 /* fid/vid correctness check for k8 */
856 /* fid are the lower 8 bits of the index we stored into 967 /* fid are the lower 8 bits of the index we stored into
857 * the cpufreq frequency table in find_psb_table, vid are 968 * the cpufreq frequency table in find_psb_table, vid
858 * the upper 8 bits. 969 * are the upper 8 bits.
859 */ 970 */
860
861 fid = data->powernow_table[index].index & 0xFF; 971 fid = data->powernow_table[index].index & 0xFF;
862 vid = (data->powernow_table[index].index & 0xFF00) >> 8; 972 vid = (data->powernow_table[index].index & 0xFF00) >> 8;
863 973
@@ -881,22 +991,58 @@ static int transition_frequency(struct powernow_k8_data *data, unsigned int inde
881 991
882 dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n", 992 dprintk("cpu %d, changing to fid 0x%x, vid 0x%x\n",
883 smp_processor_id(), fid, vid); 993 smp_processor_id(), fid, vid);
884
885 freqs.cpu = data->cpu;
886 freqs.old = find_khz_freq_from_fid(data->currfid); 994 freqs.old = find_khz_freq_from_fid(data->currfid);
887 freqs.new = find_khz_freq_from_fid(fid); 995 freqs.new = find_khz_freq_from_fid(fid);
888 for_each_cpu_mask(i, cpu_core_map[data->cpu]) { 996
997 for_each_cpu_mask(i, *(data->available_cores)) {
889 freqs.cpu = i; 998 freqs.cpu = i;
890 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); 999 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
891 } 1000 }
892 1001
893 res = transition_fid_vid(data, fid, vid); 1002 res = transition_fid_vid(data, fid, vid);
894
895 freqs.new = find_khz_freq_from_fid(data->currfid); 1003 freqs.new = find_khz_freq_from_fid(data->currfid);
896 for_each_cpu_mask(i, cpu_core_map[data->cpu]) { 1004
1005 for_each_cpu_mask(i, *(data->available_cores)) {
897 freqs.cpu = i; 1006 freqs.cpu = i;
898 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); 1007 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
899 } 1008 }
1009 return res;
1010}
1011
1012/* Take a frequency, and issue the hardware pstate transition command */
1013static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index)
1014{
1015 u32 fid = 0;
1016 u32 did = 0;
1017 u32 pstate = 0;
1018 int res, i;
1019 struct cpufreq_freqs freqs;
1020
1021 dprintk("cpu %d transition to index %u\n", smp_processor_id(), index);
1022
1023 /* get fid did for hardware pstate transition */
1024 pstate = index & HW_PSTATE_MASK;
1025 if (pstate > MAX_HW_PSTATE)
1026 return 0;
1027 fid = (index & HW_FID_INDEX_MASK) >> HW_FID_INDEX_SHIFT;
1028 did = (index & HW_DID_INDEX_MASK) >> HW_DID_INDEX_SHIFT;
1029 freqs.old = find_khz_freq_from_fiddid(data->currfid, data->currdid);
1030 freqs.new = find_khz_freq_from_fiddid(fid, did);
1031
1032 for_each_cpu_mask(i, *(data->available_cores)) {
1033 freqs.cpu = i;
1034 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1035 }
1036
1037 res = transition_pstate(data, pstate);
1038 data->currfid = find_fid_from_pstate(pstate);
1039 data->currdid = find_did_from_pstate(pstate);
1040 freqs.new = find_khz_freq_from_fiddid(data->currfid, data->currdid);
1041
1042 for_each_cpu_mask(i, *(data->available_cores)) {
1043 freqs.cpu = i;
1044 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1045 }
900 return res; 1046 return res;
901} 1047}
902 1048
@@ -933,18 +1079,21 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
933 dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n", 1079 dprintk("targ: cpu %d, %d kHz, min %d, max %d, relation %d\n",
934 pol->cpu, targfreq, pol->min, pol->max, relation); 1080 pol->cpu, targfreq, pol->min, pol->max, relation);
935 1081
936 if (query_current_values_with_pending_wait(data)) { 1082 if (query_current_values_with_pending_wait(data))
937 ret = -EIO;
938 goto err_out; 1083 goto err_out;
939 }
940 1084
941 dprintk("targ: curr fid 0x%x, vid 0x%x\n", 1085 if (cpu_family)
1086 dprintk("targ: curr fid 0x%x, did 0x%x\n",
1087 data->currfid, data->currvid);
1088 else {
1089 dprintk("targ: curr fid 0x%x, vid 0x%x\n",
942 data->currfid, data->currvid); 1090 data->currfid, data->currvid);
943 1091
944 if ((checkvid != data->currvid) || (checkfid != data->currfid)) { 1092 if ((checkvid != data->currvid) || (checkfid != data->currfid)) {
945 printk(KERN_INFO PFX 1093 printk(KERN_INFO PFX
946 "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", 1094 "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
947 checkfid, data->currfid, checkvid, data->currvid); 1095 checkfid, data->currfid, checkvid, data->currvid);
1096 }
948 } 1097 }
949 1098
950 if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) 1099 if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate))
@@ -954,7 +1103,11 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
954 1103
955 powernow_k8_acpi_pst_values(data, newstate); 1104 powernow_k8_acpi_pst_values(data, newstate);
956 1105
957 if (transition_frequency(data, newstate)) { 1106 if (cpu_family)
1107 ret = transition_frequency_pstate(data, newstate);
1108 else
1109 ret = transition_frequency_fidvid(data, newstate);
1110 if (ret) {
958 printk(KERN_ERR PFX "transition frequency failed\n"); 1111 printk(KERN_ERR PFX "transition frequency failed\n");
959 ret = 1; 1112 ret = 1;
960 mutex_unlock(&fidvid_mutex); 1113 mutex_unlock(&fidvid_mutex);
@@ -962,7 +1115,10 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi
962 } 1115 }
963 mutex_unlock(&fidvid_mutex); 1116 mutex_unlock(&fidvid_mutex);
964 1117
965 pol->cur = find_khz_freq_from_fid(data->currfid); 1118 if (cpu_family)
1119 pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
1120 else
1121 pol->cur = find_khz_freq_from_fid(data->currfid);
966 ret = 0; 1122 ret = 0;
967 1123
968err_out: 1124err_out:
@@ -1007,14 +1163,13 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1007 * Use the PSB BIOS structure. This is only availabe on 1163 * Use the PSB BIOS structure. This is only availabe on
1008 * an UP version, and is deprecated by AMD. 1164 * an UP version, and is deprecated by AMD.
1009 */ 1165 */
1010
1011 if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) { 1166 if ((num_online_cpus() != 1) || (num_possible_cpus() != 1)) {
1012 printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n"); 1167 printk(KERN_ERR PFX "MP systems not supported by PSB BIOS structure\n");
1013 kfree(data); 1168 kfree(data);
1014 return -ENODEV; 1169 return -ENODEV;
1015 } 1170 }
1016 if (pol->cpu != 0) { 1171 if (pol->cpu != 0) {
1017 printk(KERN_ERR PFX "init not cpu 0\n"); 1172 printk(KERN_ERR PFX "No _PSS objects for CPU other than CPU0\n");
1018 kfree(data); 1173 kfree(data);
1019 return -ENODEV; 1174 return -ENODEV;
1020 } 1175 }
@@ -1042,20 +1197,28 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1042 if (query_current_values_with_pending_wait(data)) 1197 if (query_current_values_with_pending_wait(data))
1043 goto err_out; 1198 goto err_out;
1044 1199
1045 fidvid_msr_init(); 1200 if (!cpu_family)
1201 fidvid_msr_init();
1046 1202
1047 /* run on any CPU again */ 1203 /* run on any CPU again */
1048 set_cpus_allowed(current, oldmask); 1204 set_cpus_allowed(current, oldmask);
1049 1205
1050 pol->governor = CPUFREQ_DEFAULT_GOVERNOR; 1206 pol->governor = CPUFREQ_DEFAULT_GOVERNOR;
1051 pol->cpus = cpu_core_map[pol->cpu]; 1207 if (cpu_family)
1208 pol->cpus = cpumask_of_cpu(pol->cpu);
1209 else
1210 pol->cpus = cpu_core_map[pol->cpu];
1211 data->available_cores = &(pol->cpus);
1052 1212
1053 /* Take a crude guess here. 1213 /* Take a crude guess here.
1054 * That guess was in microseconds, so multiply with 1000 */ 1214 * That guess was in microseconds, so multiply with 1000 */
1055 pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US) 1215 pol->cpuinfo.transition_latency = (((data->rvo + 8) * data->vstable * VST_UNITS_20US)
1056 + (3 * (1 << data->irt) * 10)) * 1000; 1216 + (3 * (1 << data->irt) * 10)) * 1000;
1057 1217
1058 pol->cur = find_khz_freq_from_fid(data->currfid); 1218 if (cpu_family)
1219 pol->cur = find_khz_freq_from_fiddid(data->currfid, data->currdid);
1220 else
1221 pol->cur = find_khz_freq_from_fid(data->currfid);
1059 dprintk("policy current frequency %d kHz\n", pol->cur); 1222 dprintk("policy current frequency %d kHz\n", pol->cur);
1060 1223
1061 /* min/max the cpu is capable of */ 1224 /* min/max the cpu is capable of */
@@ -1069,8 +1232,12 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1069 1232
1070 cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); 1233 cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
1071 1234
1072 printk("cpu_init done, current fid 0x%x, vid 0x%x\n", 1235 if (cpu_family)
1073 data->currfid, data->currvid); 1236 dprintk("cpu_init done, current fid 0x%x, did 0x%x\n",
1237 data->currfid, data->currdid);
1238 else
1239 dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n",
1240 data->currfid, data->currvid);
1074 1241
1075 powernow_data[pol->cpu] = data; 1242 powernow_data[pol->cpu] = data;
1076 1243
@@ -1156,8 +1323,9 @@ static int __cpuinit powernowk8_init(void)
1156 } 1323 }
1157 1324
1158 if (supported_cpus == num_online_cpus()) { 1325 if (supported_cpus == num_online_cpus()) {
1159 printk(KERN_INFO PFX "Found %d AMD Athlon 64 / Opteron " 1326 printk(KERN_INFO PFX "Found %d %s "
1160 "processors (" VERSION ")\n", supported_cpus); 1327 "processors (" VERSION ")\n", supported_cpus,
1328 boot_cpu_data.x86_model_id);
1161 return cpufreq_register_driver(&cpufreq_amd64_driver); 1329 return cpufreq_register_driver(&cpufreq_amd64_driver);
1162 } 1330 }
1163 1331
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
index 79a7c5c87edc..bf8ad9e43da3 100644
--- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
+++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * (c) 2003, 2004, 2005 Advanced Micro Devices, Inc. 2 * (c) 2003-2006 Advanced Micro Devices, Inc.
3 * Your use of this code is subject to the terms and conditions of the 3 * Your use of this code is subject to the terms and conditions of the
4 * GNU general public license version 2. See "COPYING" or 4 * GNU general public license version 2. See "COPYING" or
5 * http://www.gnu.org/licenses/gpl.html 5 * http://www.gnu.org/licenses/gpl.html
@@ -21,8 +21,8 @@ struct powernow_k8_data {
21 u32 plllock; /* pll lock time, units 1 us */ 21 u32 plllock; /* pll lock time, units 1 us */
22 u32 exttype; /* extended interface = 1 */ 22 u32 exttype; /* extended interface = 1 */
23 23
24 /* keep track of the current fid / vid */ 24 /* keep track of the current fid / vid or did */
25 u32 currvid, currfid; 25 u32 currvid, currfid, currdid;
26 26
27 /* the powernow_table includes all frequency and vid/fid pairings: 27 /* the powernow_table includes all frequency and vid/fid pairings:
28 * fid are the lower 8 bits of the index, vid are the upper 8 bits. 28 * fid are the lower 8 bits of the index, vid are the upper 8 bits.
@@ -34,6 +34,10 @@ struct powernow_k8_data {
34 * used to determine valid frequency/vid/fid states */ 34 * used to determine valid frequency/vid/fid states */
35 struct acpi_processor_performance acpi_data; 35 struct acpi_processor_performance acpi_data;
36#endif 36#endif
37 /* we need to keep track of associated cores, but let cpufreq
38 * handle hotplug events - so just point at cpufreq pol->cpus
39 * structure */
40 cpumask_t *available_cores;
37}; 41};
38 42
39 43
@@ -43,6 +47,7 @@ struct powernow_k8_data {
43#define CPUID_XFAM_K8 0 47#define CPUID_XFAM_K8 0
44#define CPUID_XMOD 0x000f0000 /* extended model */ 48#define CPUID_XMOD 0x000f0000 /* extended model */
45#define CPUID_XMOD_REV_G 0x00060000 49#define CPUID_XMOD_REV_G 0x00060000
50#define CPUID_XFAM_10H 0x00100000 /* family 0x10 */
46#define CPUID_USE_XFAM_XMOD 0x00000f00 51#define CPUID_USE_XFAM_XMOD 0x00000f00
47#define CPUID_GET_MAX_CAPABILITIES 0x80000000 52#define CPUID_GET_MAX_CAPABILITIES 0x80000000
48#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007 53#define CPUID_FREQ_VOLT_CAPABILITIES 0x80000007
@@ -79,6 +84,32 @@ struct powernow_k8_data {
79#define MSR_S_HI_CURRENT_VID 0x0000003f 84#define MSR_S_HI_CURRENT_VID 0x0000003f
80#define MSR_C_HI_STP_GNT_BENIGN 0x00000001 85#define MSR_C_HI_STP_GNT_BENIGN 0x00000001
81 86
87
88/* Hardware Pstate _PSS and MSR definitions */
89#define USE_HW_PSTATE 0x00000080
90#define HW_PSTATE_FID_MASK 0x0000003f
91#define HW_PSTATE_DID_MASK 0x000001c0
92#define HW_PSTATE_DID_SHIFT 6
93#define HW_PSTATE_MASK 0x00000007
94#define HW_PSTATE_VALID_MASK 0x80000000
95#define HW_FID_INDEX_SHIFT 8
96#define HW_FID_INDEX_MASK 0x0000ff00
97#define HW_DID_INDEX_SHIFT 16
98#define HW_DID_INDEX_MASK 0x00ff0000
99#define HW_WATTS_MASK 0xff
100#define HW_PWR_DVR_MASK 0x300
101#define HW_PWR_DVR_SHIFT 8
102#define HW_PWR_MAX_MULT 3
103#define MAX_HW_PSTATE 8 /* hw pstate supports up to 8 */
104#define MSR_PSTATE_DEF_BASE 0xc0010064 /* base of Pstate MSRs */
105#define MSR_PSTATE_STATUS 0xc0010063 /* Pstate Status MSR */
106#define MSR_PSTATE_CTRL 0xc0010062 /* Pstate control MSR */
107
108/* define the two driver architectures */
109#define CPU_OPTERON 0
110#define CPU_HW_PSTATE 1
111
112
82/* 113/*
83 * There are restrictions frequencies have to follow: 114 * There are restrictions frequencies have to follow:
84 * - only 1 entry in the low fid table ( <=1.4GHz ) 115 * - only 1 entry in the low fid table ( <=1.4GHz )
@@ -182,6 +213,9 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid);
182 213
183static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index); 214static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index);
184 215
216static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
217static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table);
218
185#ifdef CONFIG_SMP 219#ifdef CONFIG_SMP
186static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[]) 220static inline void define_siblings(int cpu, cpumask_t cpu_sharedcore_mask[])
187{ 221{
diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
index b0ff9075708c..ce54ff12c15d 100644
--- a/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
+++ b/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c
@@ -250,7 +250,7 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
250 250
251 if (model->cpu_id == NULL) { 251 if (model->cpu_id == NULL) {
252 /* No match at all */ 252 /* No match at all */
253 dprintk(KERN_INFO PFX "no support for CPU model \"%s\": " 253 dprintk("no support for CPU model \"%s\": "
254 "send /proc/cpuinfo to " MAINTAINER "\n", 254 "send /proc/cpuinfo to " MAINTAINER "\n",
255 cpu->x86_model_id); 255 cpu->x86_model_id);
256 return -ENOENT; 256 return -ENOENT;
@@ -258,10 +258,10 @@ static int centrino_cpu_init_table(struct cpufreq_policy *policy)
258 258
259 if (model->op_points == NULL) { 259 if (model->op_points == NULL) {
260 /* Matched a non-match */ 260 /* Matched a non-match */
261 dprintk(KERN_INFO PFX "no table support for CPU model \"%s\"\n", 261 dprintk("no table support for CPU model \"%s\"\n",
262 cpu->x86_model_id); 262 cpu->x86_model_id);
263#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI 263#ifndef CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI
264 dprintk(KERN_INFO PFX "try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n"); 264 dprintk("try compiling with CONFIG_X86_SPEEDSTEP_CENTRINO_ACPI enabled\n");
265#endif 265#endif
266 return -ENOENT; 266 return -ENOENT;
267 } 267 }
@@ -368,7 +368,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
368 368
369 /* register with ACPI core */ 369 /* register with ACPI core */
370 if (acpi_processor_register_performance(&p, cpu)) { 370 if (acpi_processor_register_performance(&p, cpu)) {
371 dprintk(KERN_INFO PFX "obtaining ACPI data failed\n"); 371 dprintk("obtaining ACPI data failed\n");
372 return -EIO; 372 return -EIO;
373 } 373 }
374 374
@@ -465,7 +465,7 @@ static int centrino_cpu_init_acpi(struct cpufreq_policy *policy)
465 kfree(centrino_model[cpu]); 465 kfree(centrino_model[cpu]);
466 err_unreg: 466 err_unreg:
467 acpi_processor_unregister_performance(&p, cpu); 467 acpi_processor_unregister_performance(&p, cpu);
468 dprintk(KERN_INFO PFX "invalid ACPI data\n"); 468 dprintk("invalid ACPI data\n");
469 return (result); 469 return (result);
470} 470}
471#else 471#else
@@ -499,7 +499,7 @@ static int centrino_cpu_init(struct cpufreq_policy *policy)
499 centrino_cpu[policy->cpu] = &cpu_ids[i]; 499 centrino_cpu[policy->cpu] = &cpu_ids[i];
500 500
501 if (!centrino_cpu[policy->cpu]) { 501 if (!centrino_cpu[policy->cpu]) {
502 dprintk(KERN_INFO PFX "found unsupported CPU with " 502 dprintk("found unsupported CPU with "
503 "Enhanced SpeedStep: send /proc/cpuinfo to " 503 "Enhanced SpeedStep: send /proc/cpuinfo to "
504 MAINTAINER "\n"); 504 MAINTAINER "\n");
505 return -ENODEV; 505 return -ENODEV;