diff options
Diffstat (limited to 'arch/x86/kernel/cpu/cpufreq/powernow-k8.c')
-rw-r--r-- | arch/x86/kernel/cpu/cpufreq/powernow-k8.c | 386 |
1 files changed, 233 insertions, 153 deletions
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c index e8fd76f98883..4709ead2db52 100644 --- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -33,16 +33,14 @@ | |||
33 | #include <linux/string.h> | 33 | #include <linux/string.h> |
34 | #include <linux/cpumask.h> | 34 | #include <linux/cpumask.h> |
35 | #include <linux/sched.h> /* for current / set_cpus_allowed() */ | 35 | #include <linux/sched.h> /* for current / set_cpus_allowed() */ |
36 | #include <linux/io.h> | ||
37 | #include <linux/delay.h> | ||
36 | 38 | ||
37 | #include <asm/msr.h> | 39 | #include <asm/msr.h> |
38 | #include <asm/io.h> | ||
39 | #include <asm/delay.h> | ||
40 | 40 | ||
41 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | ||
42 | #include <linux/acpi.h> | 41 | #include <linux/acpi.h> |
43 | #include <linux/mutex.h> | 42 | #include <linux/mutex.h> |
44 | #include <acpi/processor.h> | 43 | #include <acpi/processor.h> |
45 | #endif | ||
46 | 44 | ||
47 | #define PFX "powernow-k8: " | 45 | #define PFX "powernow-k8: " |
48 | #define VERSION "version 2.20.00" | 46 | #define VERSION "version 2.20.00" |
@@ -74,7 +72,8 @@ static u32 find_khz_freq_from_fid(u32 fid) | |||
74 | return 1000 * find_freq_from_fid(fid); | 72 | return 1000 * find_freq_from_fid(fid); |
75 | } | 73 | } |
76 | 74 | ||
77 | static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, u32 pstate) | 75 | static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data, |
76 | u32 pstate) | ||
78 | { | 77 | { |
79 | return data[pstate].frequency; | 78 | return data[pstate].frequency; |
80 | } | 79 | } |
@@ -189,7 +188,9 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
189 | return 1; | 188 | return 1; |
190 | } | 189 | } |
191 | 190 | ||
192 | lo = fid | (data->currvid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID; | 191 | lo = fid; |
192 | lo |= (data->currvid << MSR_C_LO_VID_SHIFT); | ||
193 | lo |= MSR_C_LO_INIT_FID_VID; | ||
193 | 194 | ||
194 | dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n", | 195 | dprintk("writing fid 0x%x, lo 0x%x, hi 0x%x\n", |
195 | fid, lo, data->plllock * PLL_LOCK_CONVERSION); | 196 | fid, lo, data->plllock * PLL_LOCK_CONVERSION); |
@@ -197,7 +198,9 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
197 | do { | 198 | do { |
198 | wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); | 199 | wrmsr(MSR_FIDVID_CTL, lo, data->plllock * PLL_LOCK_CONVERSION); |
199 | if (i++ > 100) { | 200 | if (i++ > 100) { |
200 | printk(KERN_ERR PFX "Hardware error - pending bit very stuck - no further pstate changes possible\n"); | 201 | printk(KERN_ERR PFX |
202 | "Hardware error - pending bit very stuck - " | ||
203 | "no further pstate changes possible\n"); | ||
201 | return 1; | 204 | return 1; |
202 | } | 205 | } |
203 | } while (query_current_values_with_pending_wait(data)); | 206 | } while (query_current_values_with_pending_wait(data)); |
@@ -205,14 +208,16 @@ static int write_new_fid(struct powernow_k8_data *data, u32 fid) | |||
205 | count_off_irt(data); | 208 | count_off_irt(data); |
206 | 209 | ||
207 | if (savevid != data->currvid) { | 210 | if (savevid != data->currvid) { |
208 | printk(KERN_ERR PFX "vid change on fid trans, old 0x%x, new 0x%x\n", | 211 | printk(KERN_ERR PFX |
209 | savevid, data->currvid); | 212 | "vid change on fid trans, old 0x%x, new 0x%x\n", |
213 | savevid, data->currvid); | ||
210 | return 1; | 214 | return 1; |
211 | } | 215 | } |
212 | 216 | ||
213 | if (fid != data->currfid) { | 217 | if (fid != data->currfid) { |
214 | printk(KERN_ERR PFX "fid trans failed, fid 0x%x, curr 0x%x\n", fid, | 218 | printk(KERN_ERR PFX |
215 | data->currfid); | 219 | "fid trans failed, fid 0x%x, curr 0x%x\n", fid, |
220 | data->currfid); | ||
216 | return 1; | 221 | return 1; |
217 | } | 222 | } |
218 | 223 | ||
@@ -231,7 +236,9 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
231 | return 1; | 236 | return 1; |
232 | } | 237 | } |
233 | 238 | ||
234 | lo = data->currfid | (vid << MSR_C_LO_VID_SHIFT) | MSR_C_LO_INIT_FID_VID; | 239 | lo = data->currfid; |
240 | lo |= (vid << MSR_C_LO_VID_SHIFT); | ||
241 | lo |= MSR_C_LO_INIT_FID_VID; | ||
235 | 242 | ||
236 | dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n", | 243 | dprintk("writing vid 0x%x, lo 0x%x, hi 0x%x\n", |
237 | vid, lo, STOP_GRANT_5NS); | 244 | vid, lo, STOP_GRANT_5NS); |
@@ -239,20 +246,24 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
239 | do { | 246 | do { |
240 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); | 247 | wrmsr(MSR_FIDVID_CTL, lo, STOP_GRANT_5NS); |
241 | if (i++ > 100) { | 248 | if (i++ > 100) { |
242 | printk(KERN_ERR PFX "internal error - pending bit very stuck - no further pstate changes possible\n"); | 249 | printk(KERN_ERR PFX "internal error - pending bit " |
250 | "very stuck - no further pstate " | ||
251 | "changes possible\n"); | ||
243 | return 1; | 252 | return 1; |
244 | } | 253 | } |
245 | } while (query_current_values_with_pending_wait(data)); | 254 | } while (query_current_values_with_pending_wait(data)); |
246 | 255 | ||
247 | if (savefid != data->currfid) { | 256 | if (savefid != data->currfid) { |
248 | printk(KERN_ERR PFX "fid changed on vid trans, old 0x%x new 0x%x\n", | 257 | printk(KERN_ERR PFX "fid changed on vid trans, old " |
258 | "0x%x new 0x%x\n", | ||
249 | savefid, data->currfid); | 259 | savefid, data->currfid); |
250 | return 1; | 260 | return 1; |
251 | } | 261 | } |
252 | 262 | ||
253 | if (vid != data->currvid) { | 263 | if (vid != data->currvid) { |
254 | printk(KERN_ERR PFX "vid trans failed, vid 0x%x, curr 0x%x\n", vid, | 264 | printk(KERN_ERR PFX "vid trans failed, vid 0x%x, " |
255 | data->currvid); | 265 | "curr 0x%x\n", |
266 | vid, data->currvid); | ||
256 | return 1; | 267 | return 1; |
257 | } | 268 | } |
258 | 269 | ||
@@ -264,7 +275,8 @@ static int write_new_vid(struct powernow_k8_data *data, u32 vid) | |||
264 | * Decreasing vid codes represent increasing voltages: | 275 | * Decreasing vid codes represent increasing voltages: |
265 | * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off. | 276 | * vid of 0 is 1.550V, vid of 0x1e is 0.800V, vid of VID_OFF is off. |
266 | */ | 277 | */ |
267 | static int decrease_vid_code_by_step(struct powernow_k8_data *data, u32 reqvid, u32 step) | 278 | static int decrease_vid_code_by_step(struct powernow_k8_data *data, |
279 | u32 reqvid, u32 step) | ||
268 | { | 280 | { |
269 | if ((data->currvid - reqvid) > step) | 281 | if ((data->currvid - reqvid) > step) |
270 | reqvid = data->currvid - step; | 282 | reqvid = data->currvid - step; |
@@ -286,7 +298,8 @@ static int transition_pstate(struct powernow_k8_data *data, u32 pstate) | |||
286 | } | 298 | } |
287 | 299 | ||
288 | /* Change Opteron/Athlon64 fid and vid, by the 3 phases. */ | 300 | /* Change Opteron/Athlon64 fid and vid, by the 3 phases. */ |
289 | static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 reqvid) | 301 | static int transition_fid_vid(struct powernow_k8_data *data, |
302 | u32 reqfid, u32 reqvid) | ||
290 | { | 303 | { |
291 | if (core_voltage_pre_transition(data, reqvid)) | 304 | if (core_voltage_pre_transition(data, reqvid)) |
292 | return 1; | 305 | return 1; |
@@ -301,7 +314,8 @@ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 req | |||
301 | return 1; | 314 | return 1; |
302 | 315 | ||
303 | if ((reqfid != data->currfid) || (reqvid != data->currvid)) { | 316 | if ((reqfid != data->currfid) || (reqvid != data->currvid)) { |
304 | printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, curr 0x%x 0x%x\n", | 317 | printk(KERN_ERR PFX "failed (cpu%d): req 0x%x 0x%x, " |
318 | "curr 0x%x 0x%x\n", | ||
305 | smp_processor_id(), | 319 | smp_processor_id(), |
306 | reqfid, reqvid, data->currfid, data->currvid); | 320 | reqfid, reqvid, data->currfid, data->currvid); |
307 | return 1; | 321 | return 1; |
@@ -314,13 +328,15 @@ static int transition_fid_vid(struct powernow_k8_data *data, u32 reqfid, u32 req | |||
314 | } | 328 | } |
315 | 329 | ||
316 | /* Phase 1 - core voltage transition ... setup voltage */ | 330 | /* Phase 1 - core voltage transition ... setup voltage */ |
317 | static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid) | 331 | static int core_voltage_pre_transition(struct powernow_k8_data *data, |
332 | u32 reqvid) | ||
318 | { | 333 | { |
319 | u32 rvosteps = data->rvo; | 334 | u32 rvosteps = data->rvo; |
320 | u32 savefid = data->currfid; | 335 | u32 savefid = data->currfid; |
321 | u32 maxvid, lo; | 336 | u32 maxvid, lo; |
322 | 337 | ||
323 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, reqvid 0x%x, rvo 0x%x\n", | 338 | dprintk("ph1 (cpu%d): start, currfid 0x%x, currvid 0x%x, " |
339 | "reqvid 0x%x, rvo 0x%x\n", | ||
324 | smp_processor_id(), | 340 | smp_processor_id(), |
325 | data->currfid, data->currvid, reqvid, data->rvo); | 341 | data->currfid, data->currvid, reqvid, data->rvo); |
326 | 342 | ||
@@ -343,7 +359,7 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
343 | } else { | 359 | } else { |
344 | dprintk("ph1: changing vid for rvo, req 0x%x\n", | 360 | dprintk("ph1: changing vid for rvo, req 0x%x\n", |
345 | data->currvid - 1); | 361 | data->currvid - 1); |
346 | if (decrease_vid_code_by_step(data, data->currvid - 1, 1)) | 362 | if (decrease_vid_code_by_step(data, data->currvid-1, 1)) |
347 | return 1; | 363 | return 1; |
348 | rvosteps--; | 364 | rvosteps--; |
349 | } | 365 | } |
@@ -353,7 +369,8 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
353 | return 1; | 369 | return 1; |
354 | 370 | ||
355 | if (savefid != data->currfid) { | 371 | if (savefid != data->currfid) { |
356 | printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", data->currfid); | 372 | printk(KERN_ERR PFX "ph1 err, currfid changed 0x%x\n", |
373 | data->currfid); | ||
357 | return 1; | 374 | return 1; |
358 | } | 375 | } |
359 | 376 | ||
@@ -366,20 +383,24 @@ static int core_voltage_pre_transition(struct powernow_k8_data *data, u32 reqvid | |||
366 | /* Phase 2 - core frequency transition */ | 383 | /* Phase 2 - core frequency transition */ |
367 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | 384 | static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) |
368 | { | 385 | { |
369 | u32 vcoreqfid, vcocurrfid, vcofiddiff, fid_interval, savevid = data->currvid; | 386 | u32 vcoreqfid, vcocurrfid, vcofiddiff; |
387 | u32 fid_interval, savevid = data->currvid; | ||
370 | 388 | ||
371 | if ((reqfid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 389 | if ((reqfid < HI_FID_TABLE_BOTTOM) && |
372 | printk(KERN_ERR PFX "ph2: illegal lo-lo transition 0x%x 0x%x\n", | 390 | (data->currfid < HI_FID_TABLE_BOTTOM)) { |
373 | reqfid, data->currfid); | 391 | printk(KERN_ERR PFX "ph2: illegal lo-lo transition " |
392 | "0x%x 0x%x\n", reqfid, data->currfid); | ||
374 | return 1; | 393 | return 1; |
375 | } | 394 | } |
376 | 395 | ||
377 | if (data->currfid == reqfid) { | 396 | if (data->currfid == reqfid) { |
378 | printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", data->currfid); | 397 | printk(KERN_ERR PFX "ph2 null fid transition 0x%x\n", |
398 | data->currfid); | ||
379 | return 0; | 399 | return 0; |
380 | } | 400 | } |
381 | 401 | ||
382 | dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, reqfid 0x%x\n", | 402 | dprintk("ph2 (cpu%d): starting, currfid 0x%x, currvid 0x%x, " |
403 | "reqfid 0x%x\n", | ||
383 | smp_processor_id(), | 404 | smp_processor_id(), |
384 | data->currfid, data->currvid, reqfid); | 405 | data->currfid, data->currvid, reqfid); |
385 | 406 | ||
@@ -393,14 +414,14 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
393 | 414 | ||
394 | if (reqfid > data->currfid) { | 415 | if (reqfid > data->currfid) { |
395 | if (data->currfid > LO_FID_TABLE_TOP) { | 416 | if (data->currfid > LO_FID_TABLE_TOP) { |
396 | if (write_new_fid(data, data->currfid + fid_interval)) { | 417 | if (write_new_fid(data, |
418 | data->currfid + fid_interval)) | ||
397 | return 1; | 419 | return 1; |
398 | } | ||
399 | } else { | 420 | } else { |
400 | if (write_new_fid | 421 | if (write_new_fid |
401 | (data, 2 + convert_fid_to_vco_fid(data->currfid))) { | 422 | (data, |
423 | 2 + convert_fid_to_vco_fid(data->currfid))) | ||
402 | return 1; | 424 | return 1; |
403 | } | ||
404 | } | 425 | } |
405 | } else { | 426 | } else { |
406 | if (write_new_fid(data, data->currfid - fid_interval)) | 427 | if (write_new_fid(data, data->currfid - fid_interval)) |
@@ -420,7 +441,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
420 | 441 | ||
421 | if (data->currfid != reqfid) { | 442 | if (data->currfid != reqfid) { |
422 | printk(KERN_ERR PFX | 443 | printk(KERN_ERR PFX |
423 | "ph2: mismatch, failed fid transition, curr 0x%x, req 0x%x\n", | 444 | "ph2: mismatch, failed fid transition, " |
445 | "curr 0x%x, req 0x%x\n", | ||
424 | data->currfid, reqfid); | 446 | data->currfid, reqfid); |
425 | return 1; | 447 | return 1; |
426 | } | 448 | } |
@@ -438,7 +460,8 @@ static int core_frequency_transition(struct powernow_k8_data *data, u32 reqfid) | |||
438 | } | 460 | } |
439 | 461 | ||
440 | /* Phase 3 - core voltage transition flow ... jump to the final vid. */ | 462 | /* Phase 3 - core voltage transition flow ... jump to the final vid. */ |
441 | static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvid) | 463 | static int core_voltage_post_transition(struct powernow_k8_data *data, |
464 | u32 reqvid) | ||
442 | { | 465 | { |
443 | u32 savefid = data->currfid; | 466 | u32 savefid = data->currfid; |
444 | u32 savereqvid = reqvid; | 467 | u32 savereqvid = reqvid; |
@@ -460,7 +483,8 @@ static int core_voltage_post_transition(struct powernow_k8_data *data, u32 reqvi | |||
460 | 483 | ||
461 | if (data->currvid != reqvid) { | 484 | if (data->currvid != reqvid) { |
462 | printk(KERN_ERR PFX | 485 | printk(KERN_ERR PFX |
463 | "ph3: failed vid transition\n, req 0x%x, curr 0x%x", | 486 | "ph3: failed vid transition\n, " |
487 | "req 0x%x, curr 0x%x", | ||
464 | reqvid, data->currvid); | 488 | reqvid, data->currvid); |
465 | return 1; | 489 | return 1; |
466 | } | 490 | } |
@@ -511,7 +535,8 @@ static int check_supported_cpu(unsigned int cpu) | |||
511 | if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { | 535 | if ((eax & CPUID_XFAM) == CPUID_XFAM_K8) { |
512 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || | 536 | if (((eax & CPUID_USE_XFAM_XMOD) != CPUID_USE_XFAM_XMOD) || |
513 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { | 537 | ((eax & CPUID_XMOD) > CPUID_XMOD_REV_MASK)) { |
514 | printk(KERN_INFO PFX "Processor cpuid %x not supported\n", eax); | 538 | printk(KERN_INFO PFX |
539 | "Processor cpuid %x not supported\n", eax); | ||
515 | goto out; | 540 | goto out; |
516 | } | 541 | } |
517 | 542 | ||
@@ -523,8 +548,10 @@ static int check_supported_cpu(unsigned int cpu) | |||
523 | } | 548 | } |
524 | 549 | ||
525 | cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); | 550 | cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx); |
526 | if ((edx & P_STATE_TRANSITION_CAPABLE) != P_STATE_TRANSITION_CAPABLE) { | 551 | if ((edx & P_STATE_TRANSITION_CAPABLE) |
527 | printk(KERN_INFO PFX "Power state transitions not supported\n"); | 552 | != P_STATE_TRANSITION_CAPABLE) { |
553 | printk(KERN_INFO PFX | ||
554 | "Power state transitions not supported\n"); | ||
528 | goto out; | 555 | goto out; |
529 | } | 556 | } |
530 | } else { /* must be a HW Pstate capable processor */ | 557 | } else { /* must be a HW Pstate capable processor */ |
@@ -542,7 +569,8 @@ out: | |||
542 | return rc; | 569 | return rc; |
543 | } | 570 | } |
544 | 571 | ||
545 | static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) | 572 | static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, |
573 | u8 maxvid) | ||
546 | { | 574 | { |
547 | unsigned int j; | 575 | unsigned int j; |
548 | u8 lastfid = 0xff; | 576 | u8 lastfid = 0xff; |
@@ -553,12 +581,14 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 | |||
553 | j, pst[j].vid); | 581 | j, pst[j].vid); |
554 | return -EINVAL; | 582 | return -EINVAL; |
555 | } | 583 | } |
556 | if (pst[j].vid < data->rvo) { /* vid + rvo >= 0 */ | 584 | if (pst[j].vid < data->rvo) { |
585 | /* vid + rvo >= 0 */ | ||
557 | printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" | 586 | printk(KERN_ERR FW_BUG PFX "0 vid exceeded with pstate" |
558 | " %d\n", j); | 587 | " %d\n", j); |
559 | return -ENODEV; | 588 | return -ENODEV; |
560 | } | 589 | } |
561 | if (pst[j].vid < maxvid + data->rvo) { /* vid + rvo >= maxvid */ | 590 | if (pst[j].vid < maxvid + data->rvo) { |
591 | /* vid + rvo >= maxvid */ | ||
562 | printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" | 592 | printk(KERN_ERR FW_BUG PFX "maxvid exceeded with pstate" |
563 | " %d\n", j); | 593 | " %d\n", j); |
564 | return -ENODEV; | 594 | return -ENODEV; |
@@ -582,23 +612,31 @@ static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, u8 | |||
582 | return -EINVAL; | 612 | return -EINVAL; |
583 | } | 613 | } |
584 | if (lastfid > LO_FID_TABLE_TOP) | 614 | if (lastfid > LO_FID_TABLE_TOP) |
585 | printk(KERN_INFO FW_BUG PFX "first fid not from lo freq table\n"); | 615 | printk(KERN_INFO FW_BUG PFX |
616 | "first fid not from lo freq table\n"); | ||
586 | 617 | ||
587 | return 0; | 618 | return 0; |
588 | } | 619 | } |
589 | 620 | ||
621 | static void invalidate_entry(struct powernow_k8_data *data, unsigned int entry) | ||
622 | { | ||
623 | data->powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID; | ||
624 | } | ||
625 | |||
590 | static void print_basics(struct powernow_k8_data *data) | 626 | static void print_basics(struct powernow_k8_data *data) |
591 | { | 627 | { |
592 | int j; | 628 | int j; |
593 | for (j = 0; j < data->numps; j++) { | 629 | for (j = 0; j < data->numps; j++) { |
594 | if (data->powernow_table[j].frequency != CPUFREQ_ENTRY_INVALID) { | 630 | if (data->powernow_table[j].frequency != |
631 | CPUFREQ_ENTRY_INVALID) { | ||
595 | if (cpu_family == CPU_HW_PSTATE) { | 632 | if (cpu_family == CPU_HW_PSTATE) { |
596 | printk(KERN_INFO PFX " %d : pstate %d (%d MHz)\n", | 633 | printk(KERN_INFO PFX |
597 | j, | 634 | " %d : pstate %d (%d MHz)\n", j, |
598 | data->powernow_table[j].index, | 635 | data->powernow_table[j].index, |
599 | data->powernow_table[j].frequency/1000); | 636 | data->powernow_table[j].frequency/1000); |
600 | } else { | 637 | } else { |
601 | printk(KERN_INFO PFX " %d : fid 0x%x (%d MHz), vid 0x%x\n", | 638 | printk(KERN_INFO PFX |
639 | " %d : fid 0x%x (%d MHz), vid 0x%x\n", | ||
602 | j, | 640 | j, |
603 | data->powernow_table[j].index & 0xff, | 641 | data->powernow_table[j].index & 0xff, |
604 | data->powernow_table[j].frequency/1000, | 642 | data->powernow_table[j].frequency/1000, |
@@ -607,20 +645,25 @@ static void print_basics(struct powernow_k8_data *data) | |||
607 | } | 645 | } |
608 | } | 646 | } |
609 | if (data->batps) | 647 | if (data->batps) |
610 | printk(KERN_INFO PFX "Only %d pstates on battery\n", data->batps); | 648 | printk(KERN_INFO PFX "Only %d pstates on battery\n", |
649 | data->batps); | ||
611 | } | 650 | } |
612 | 651 | ||
613 | static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, u8 maxvid) | 652 | static int fill_powernow_table(struct powernow_k8_data *data, |
653 | struct pst_s *pst, u8 maxvid) | ||
614 | { | 654 | { |
615 | struct cpufreq_frequency_table *powernow_table; | 655 | struct cpufreq_frequency_table *powernow_table; |
616 | unsigned int j; | 656 | unsigned int j; |
617 | 657 | ||
618 | if (data->batps) { /* use ACPI support to get full speed on mains power */ | 658 | if (data->batps) { |
619 | printk(KERN_WARNING PFX "Only %d pstates usable (use ACPI driver for full range\n", data->batps); | 659 | /* use ACPI support to get full speed on mains power */ |
660 | printk(KERN_WARNING PFX | ||
661 | "Only %d pstates usable (use ACPI driver for full " | ||
662 | "range\n", data->batps); | ||
620 | data->numps = data->batps; | 663 | data->numps = data->batps; |
621 | } | 664 | } |
622 | 665 | ||
623 | for ( j=1; j<data->numps; j++ ) { | 666 | for (j = 1; j < data->numps; j++) { |
624 | if (pst[j-1].fid >= pst[j].fid) { | 667 | if (pst[j-1].fid >= pst[j].fid) { |
625 | printk(KERN_ERR PFX "PST out of sequence\n"); | 668 | printk(KERN_ERR PFX "PST out of sequence\n"); |
626 | return -EINVAL; | 669 | return -EINVAL; |
@@ -643,9 +686,11 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, | |||
643 | } | 686 | } |
644 | 687 | ||
645 | for (j = 0; j < data->numps; j++) { | 688 | for (j = 0; j < data->numps; j++) { |
689 | int freq; | ||
646 | powernow_table[j].index = pst[j].fid; /* lower 8 bits */ | 690 | powernow_table[j].index = pst[j].fid; /* lower 8 bits */ |
647 | powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */ | 691 | powernow_table[j].index |= (pst[j].vid << 8); /* upper 8 bits */ |
648 | powernow_table[j].frequency = find_khz_freq_from_fid(pst[j].fid); | 692 | freq = find_khz_freq_from_fid(pst[j].fid); |
693 | powernow_table[j].frequency = freq; | ||
649 | } | 694 | } |
650 | powernow_table[data->numps].frequency = CPUFREQ_TABLE_END; | 695 | powernow_table[data->numps].frequency = CPUFREQ_TABLE_END; |
651 | powernow_table[data->numps].index = 0; | 696 | powernow_table[data->numps].index = 0; |
@@ -661,7 +706,8 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst, | |||
661 | print_basics(data); | 706 | print_basics(data); |
662 | 707 | ||
663 | for (j = 0; j < data->numps; j++) | 708 | for (j = 0; j < data->numps; j++) |
664 | if ((pst[j].fid==data->currfid) && (pst[j].vid==data->currvid)) | 709 | if ((pst[j].fid == data->currfid) && |
710 | (pst[j].vid == data->currvid)) | ||
665 | return 0; | 711 | return 0; |
666 | 712 | ||
667 | dprintk("currfid/vid do not match PST, ignoring\n"); | 713 | dprintk("currfid/vid do not match PST, ignoring\n"); |
@@ -701,7 +747,8 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
701 | } | 747 | } |
702 | 748 | ||
703 | data->vstable = psb->vstable; | 749 | data->vstable = psb->vstable; |
704 | dprintk("voltage stabilization time: %d(*20us)\n", data->vstable); | 750 | dprintk("voltage stabilization time: %d(*20us)\n", |
751 | data->vstable); | ||
705 | 752 | ||
706 | dprintk("flags2: 0x%x\n", psb->flags2); | 753 | dprintk("flags2: 0x%x\n", psb->flags2); |
707 | data->rvo = psb->flags2 & 3; | 754 | data->rvo = psb->flags2 & 3; |
@@ -716,11 +763,12 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
716 | 763 | ||
717 | dprintk("numpst: 0x%x\n", psb->num_tables); | 764 | dprintk("numpst: 0x%x\n", psb->num_tables); |
718 | cpst = psb->num_tables; | 765 | cpst = psb->num_tables; |
719 | if ((psb->cpuid == 0x00000fc0) || (psb->cpuid == 0x00000fe0) ){ | 766 | if ((psb->cpuid == 0x00000fc0) || |
767 | (psb->cpuid == 0x00000fe0)) { | ||
720 | thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | 768 | thiscpuid = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); |
721 | if ((thiscpuid == 0x00000fc0) || (thiscpuid == 0x00000fe0) ) { | 769 | if ((thiscpuid == 0x00000fc0) || |
770 | (thiscpuid == 0x00000fe0)) | ||
722 | cpst = 1; | 771 | cpst = 1; |
723 | } | ||
724 | } | 772 | } |
725 | if (cpst != 1) { | 773 | if (cpst != 1) { |
726 | printk(KERN_ERR FW_BUG PFX "numpst must be 1\n"); | 774 | printk(KERN_ERR FW_BUG PFX "numpst must be 1\n"); |
@@ -735,7 +783,8 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
735 | 783 | ||
736 | data->numps = psb->numps; | 784 | data->numps = psb->numps; |
737 | dprintk("numpstates: 0x%x\n", data->numps); | 785 | dprintk("numpstates: 0x%x\n", data->numps); |
738 | return fill_powernow_table(data, (struct pst_s *)(psb+1), maxvid); | 786 | return fill_powernow_table(data, |
787 | (struct pst_s *)(psb+1), maxvid); | ||
739 | } | 788 | } |
740 | /* | 789 | /* |
741 | * If you see this message, complain to BIOS manufacturer. If | 790 | * If you see this message, complain to BIOS manufacturer. If |
@@ -748,28 +797,31 @@ static int find_psb_table(struct powernow_k8_data *data) | |||
748 | * BIOS and Kernel Developer's Guide, which is available on | 797 | * BIOS and Kernel Developer's Guide, which is available on |
749 | * www.amd.com | 798 | * www.amd.com |
750 | */ | 799 | */ |
751 | printk(KERN_ERR PFX "BIOS error - no PSB or ACPI _PSS objects\n"); | 800 | printk(KERN_ERR FW_BUG PFX "No PSB or ACPI _PSS objects\n"); |
752 | return -ENODEV; | 801 | return -ENODEV; |
753 | } | 802 | } |
754 | 803 | ||
755 | #ifdef CONFIG_X86_POWERNOW_K8_ACPI | 804 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, |
756 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) | 805 | unsigned int index) |
757 | { | 806 | { |
807 | acpi_integer control; | ||
808 | |||
758 | if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) | 809 | if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) |
759 | return; | 810 | return; |
760 | 811 | ||
761 | data->irt = (data->acpi_data.states[index].control >> IRT_SHIFT) & IRT_MASK; | 812 | control = data->acpi_data.states[index].control; data->irt = (control |
762 | data->rvo = (data->acpi_data.states[index].control >> RVO_SHIFT) & RVO_MASK; | 813 | >> IRT_SHIFT) & IRT_MASK; data->rvo = (control >> |
763 | data->exttype = (data->acpi_data.states[index].control >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; | 814 | RVO_SHIFT) & RVO_MASK; data->exttype = (control |
764 | data->plllock = (data->acpi_data.states[index].control >> PLL_L_SHIFT) & PLL_L_MASK; | 815 | >> EXT_TYPE_SHIFT) & EXT_TYPE_MASK; |
765 | data->vidmvs = 1 << ((data->acpi_data.states[index].control >> MVS_SHIFT) & MVS_MASK); | 816 | data->plllock = (control >> PLL_L_SHIFT) & PLL_L_MASK; data->vidmvs = 1 |
766 | data->vstable = (data->acpi_data.states[index].control >> VST_SHIFT) & VST_MASK; | 817 | << ((control >> MVS_SHIFT) & MVS_MASK); data->vstable = |
767 | } | 818 | (control >> VST_SHIFT) & VST_MASK; } |
768 | 819 | ||
769 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | 820 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) |
770 | { | 821 | { |
771 | struct cpufreq_frequency_table *powernow_table; | 822 | struct cpufreq_frequency_table *powernow_table; |
772 | int ret_val = -ENODEV; | 823 | int ret_val = -ENODEV; |
824 | acpi_integer space_id; | ||
773 | 825 | ||
774 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { | 826 | if (acpi_processor_register_performance(&data->acpi_data, data->cpu)) { |
775 | dprintk("register performance failed: bad ACPI data\n"); | 827 | dprintk("register performance failed: bad ACPI data\n"); |
@@ -782,11 +834,12 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
782 | goto err_out; | 834 | goto err_out; |
783 | } | 835 | } |
784 | 836 | ||
785 | if ((data->acpi_data.control_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || | 837 | space_id = data->acpi_data.control_register.space_id; |
786 | (data->acpi_data.status_register.space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | 838 | if ((space_id != ACPI_ADR_SPACE_FIXED_HARDWARE) || |
839 | (space_id != ACPI_ADR_SPACE_FIXED_HARDWARE)) { | ||
787 | dprintk("Invalid control/status registers (%x - %x)\n", | 840 | dprintk("Invalid control/status registers (%x - %x)\n", |
788 | data->acpi_data.control_register.space_id, | 841 | data->acpi_data.control_register.space_id, |
789 | data->acpi_data.status_register.space_id); | 842 | space_id); |
790 | goto err_out; | 843 | goto err_out; |
791 | } | 844 | } |
792 | 845 | ||
@@ -805,7 +858,8 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) | |||
805 | if (ret_val) | 858 | if (ret_val) |
806 | goto err_out_mem; | 859 | goto err_out_mem; |
807 | 860 | ||
808 | powernow_table[data->acpi_data.state_count].frequency = CPUFREQ_TABLE_END; | 861 | powernow_table[data->acpi_data.state_count].frequency = |
862 | CPUFREQ_TABLE_END; | ||
809 | powernow_table[data->acpi_data.state_count].index = 0; | 863 | powernow_table[data->acpi_data.state_count].index = 0; |
810 | data->powernow_table = powernow_table; | 864 | data->powernow_table = powernow_table; |
811 | 865 | ||
@@ -833,13 +887,15 @@ err_out_mem: | |||
833 | err_out: | 887 | err_out: |
834 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); | 888 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); |
835 | 889 | ||
836 | /* data->acpi_data.state_count informs us at ->exit() whether ACPI was used */ | 890 | /* data->acpi_data.state_count informs us at ->exit() |
891 | * whether ACPI was used */ | ||
837 | data->acpi_data.state_count = 0; | 892 | data->acpi_data.state_count = 0; |
838 | 893 | ||
839 | return ret_val; | 894 | return ret_val; |
840 | } | 895 | } |
841 | 896 | ||
842 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) | 897 | static int fill_powernow_table_pstate(struct powernow_k8_data *data, |
898 | struct cpufreq_frequency_table *powernow_table) | ||
843 | { | 899 | { |
844 | int i; | 900 | int i; |
845 | u32 hi = 0, lo = 0; | 901 | u32 hi = 0, lo = 0; |
@@ -851,84 +907,101 @@ static int fill_powernow_table_pstate(struct powernow_k8_data *data, struct cpuf | |||
851 | 907 | ||
852 | index = data->acpi_data.states[i].control & HW_PSTATE_MASK; | 908 | index = data->acpi_data.states[i].control & HW_PSTATE_MASK; |
853 | if (index > data->max_hw_pstate) { | 909 | if (index > data->max_hw_pstate) { |
854 | printk(KERN_ERR PFX "invalid pstate %d - bad value %d.\n", i, index); | 910 | printk(KERN_ERR PFX "invalid pstate %d - " |
855 | printk(KERN_ERR PFX "Please report to BIOS manufacturer\n"); | 911 | "bad value %d.\n", i, index); |
856 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 912 | printk(KERN_ERR PFX "Please report to BIOS " |
913 | "manufacturer\n"); | ||
914 | invalidate_entry(data, i); | ||
857 | continue; | 915 | continue; |
858 | } | 916 | } |
859 | rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); | 917 | rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi); |
860 | if (!(hi & HW_PSTATE_VALID_MASK)) { | 918 | if (!(hi & HW_PSTATE_VALID_MASK)) { |
861 | dprintk("invalid pstate %d, ignoring\n", index); | 919 | dprintk("invalid pstate %d, ignoring\n", index); |
862 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 920 | invalidate_entry(data, i); |
863 | continue; | 921 | continue; |
864 | } | 922 | } |
865 | 923 | ||
866 | powernow_table[i].index = index; | 924 | powernow_table[i].index = index; |
867 | 925 | ||
868 | powernow_table[i].frequency = data->acpi_data.states[i].core_frequency * 1000; | 926 | powernow_table[i].frequency = |
927 | data->acpi_data.states[i].core_frequency * 1000; | ||
869 | } | 928 | } |
870 | return 0; | 929 | return 0; |
871 | } | 930 | } |
872 | 931 | ||
873 | static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpufreq_frequency_table *powernow_table) | 932 | static int fill_powernow_table_fidvid(struct powernow_k8_data *data, |
933 | struct cpufreq_frequency_table *powernow_table) | ||
874 | { | 934 | { |
875 | int i; | 935 | int i; |
876 | int cntlofreq = 0; | 936 | int cntlofreq = 0; |
937 | |||
877 | for (i = 0; i < data->acpi_data.state_count; i++) { | 938 | for (i = 0; i < data->acpi_data.state_count; i++) { |
878 | u32 fid; | 939 | u32 fid; |
879 | u32 vid; | 940 | u32 vid; |
941 | u32 freq, index; | ||
942 | acpi_integer status, control; | ||
880 | 943 | ||
881 | if (data->exttype) { | 944 | if (data->exttype) { |
882 | fid = data->acpi_data.states[i].status & EXT_FID_MASK; | 945 | status = data->acpi_data.states[i].status; |
883 | vid = (data->acpi_data.states[i].status >> VID_SHIFT) & EXT_VID_MASK; | 946 | fid = status & EXT_FID_MASK; |
947 | vid = (status >> VID_SHIFT) & EXT_VID_MASK; | ||
884 | } else { | 948 | } else { |
885 | fid = data->acpi_data.states[i].control & FID_MASK; | 949 | control = data->acpi_data.states[i].control; |
886 | vid = (data->acpi_data.states[i].control >> VID_SHIFT) & VID_MASK; | 950 | fid = control & FID_MASK; |
951 | vid = (control >> VID_SHIFT) & VID_MASK; | ||
887 | } | 952 | } |
888 | 953 | ||
889 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); | 954 | dprintk(" %d : fid 0x%x, vid 0x%x\n", i, fid, vid); |
890 | 955 | ||
891 | powernow_table[i].index = fid; /* lower 8 bits */ | 956 | index = fid | (vid<<8); |
892 | powernow_table[i].index |= (vid << 8); /* upper 8 bits */ | 957 | powernow_table[i].index = index; |
893 | powernow_table[i].frequency = find_khz_freq_from_fid(fid); | 958 | |
959 | freq = find_khz_freq_from_fid(fid); | ||
960 | powernow_table[i].frequency = freq; | ||
894 | 961 | ||
895 | /* verify frequency is OK */ | 962 | /* verify frequency is OK */ |
896 | if ((powernow_table[i].frequency > (MAX_FREQ * 1000)) || | 963 | if ((freq > (MAX_FREQ * 1000)) || (freq < (MIN_FREQ * 1000))) { |
897 | (powernow_table[i].frequency < (MIN_FREQ * 1000))) { | 964 | dprintk("invalid freq %u kHz, ignoring\n", freq); |
898 | dprintk("invalid freq %u kHz, ignoring\n", powernow_table[i].frequency); | 965 | invalidate_entry(data, i); |
899 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | ||
900 | continue; | 966 | continue; |
901 | } | 967 | } |
902 | 968 | ||
903 | /* verify voltage is OK - BIOSs are using "off" to indicate invalid */ | 969 | /* verify voltage is OK - |
970 | * BIOSs are using "off" to indicate invalid */ | ||
904 | if (vid == VID_OFF) { | 971 | if (vid == VID_OFF) { |
905 | dprintk("invalid vid %u, ignoring\n", vid); | 972 | dprintk("invalid vid %u, ignoring\n", vid); |
906 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 973 | invalidate_entry(data, i); |
907 | continue; | 974 | continue; |
908 | } | 975 | } |
909 | 976 | ||
910 | /* verify only 1 entry from the lo frequency table */ | 977 | /* verify only 1 entry from the lo frequency table */ |
911 | if (fid < HI_FID_TABLE_BOTTOM) { | 978 | if (fid < HI_FID_TABLE_BOTTOM) { |
912 | if (cntlofreq) { | 979 | if (cntlofreq) { |
913 | /* if both entries are the same, ignore this one ... */ | 980 | /* if both entries are the same, |
914 | if ((powernow_table[i].frequency != powernow_table[cntlofreq].frequency) || | 981 | * ignore this one ... */ |
915 | (powernow_table[i].index != powernow_table[cntlofreq].index)) { | 982 | if ((freq != powernow_table[cntlofreq].frequency) || |
916 | printk(KERN_ERR PFX "Too many lo freq table entries\n"); | 983 | (index != powernow_table[cntlofreq].index)) { |
984 | printk(KERN_ERR PFX | ||
985 | "Too many lo freq table " | ||
986 | "entries\n"); | ||
917 | return 1; | 987 | return 1; |
918 | } | 988 | } |
919 | 989 | ||
920 | dprintk("double low frequency table entry, ignoring it.\n"); | 990 | dprintk("double low frequency table entry, " |
921 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 991 | "ignoring it.\n"); |
992 | invalidate_entry(data, i); | ||
922 | continue; | 993 | continue; |
923 | } else | 994 | } else |
924 | cntlofreq = i; | 995 | cntlofreq = i; |
925 | } | 996 | } |
926 | 997 | ||
927 | if (powernow_table[i].frequency != (data->acpi_data.states[i].core_frequency * 1000)) { | 998 | if (freq != (data->acpi_data.states[i].core_frequency * 1000)) { |
928 | printk(KERN_INFO PFX "invalid freq entries %u kHz vs. %u kHz\n", | 999 | printk(KERN_INFO PFX "invalid freq entries " |
929 | powernow_table[i].frequency, | 1000 | "%u kHz vs. %u kHz\n", freq, |
930 | (unsigned int) (data->acpi_data.states[i].core_frequency * 1000)); | 1001 | (unsigned int) |
931 | powernow_table[i].frequency = CPUFREQ_ENTRY_INVALID; | 1002 | (data->acpi_data.states[i].core_frequency |
1003 | * 1000)); | ||
1004 | invalidate_entry(data, i); | ||
932 | continue; | 1005 | continue; |
933 | } | 1006 | } |
934 | } | 1007 | } |
@@ -938,7 +1011,8 @@ static int fill_powernow_table_fidvid(struct powernow_k8_data *data, struct cpuf | |||
938 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) | 1011 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) |
939 | { | 1012 | { |
940 | if (data->acpi_data.state_count) | 1013 | if (data->acpi_data.state_count) |
941 | acpi_processor_unregister_performance(&data->acpi_data, data->cpu); | 1014 | acpi_processor_unregister_performance(&data->acpi_data, |
1015 | data->cpu); | ||
942 | free_cpumask_var(data->acpi_data.shared_cpu_map); | 1016 | free_cpumask_var(data->acpi_data.shared_cpu_map); |
943 | } | 1017 | } |
944 | 1018 | ||
@@ -956,15 +1030,9 @@ static int get_transition_latency(struct powernow_k8_data *data) | |||
956 | return 1000 * max_latency; | 1030 | return 1000 * max_latency; |
957 | } | 1031 | } |
958 | 1032 | ||
959 | #else | ||
960 | static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data) { return -ENODEV; } | ||
961 | static void powernow_k8_cpu_exit_acpi(struct powernow_k8_data *data) { return; } | ||
962 | static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data, unsigned int index) { return; } | ||
963 | static int get_transition_latency(struct powernow_k8_data *data) { return 0; } | ||
964 | #endif /* CONFIG_X86_POWERNOW_K8_ACPI */ | ||
965 | |||
966 | /* Take a frequency, and issue the fid/vid transition command */ | 1033 | /* Take a frequency, and issue the fid/vid transition command */ |
967 | static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned int index) | 1034 | static int transition_frequency_fidvid(struct powernow_k8_data *data, |
1035 | unsigned int index) | ||
968 | { | 1036 | { |
969 | u32 fid = 0; | 1037 | u32 fid = 0; |
970 | u32 vid = 0; | 1038 | u32 vid = 0; |
@@ -992,7 +1060,8 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i | |||
992 | return 0; | 1060 | return 0; |
993 | } | 1061 | } |
994 | 1062 | ||
995 | if ((fid < HI_FID_TABLE_BOTTOM) && (data->currfid < HI_FID_TABLE_BOTTOM)) { | 1063 | if ((fid < HI_FID_TABLE_BOTTOM) && |
1064 | (data->currfid < HI_FID_TABLE_BOTTOM)) { | ||
996 | printk(KERN_ERR PFX | 1065 | printk(KERN_ERR PFX |
997 | "ignoring illegal change in lo freq table-%x to 0x%x\n", | 1066 | "ignoring illegal change in lo freq table-%x to 0x%x\n", |
998 | data->currfid, fid); | 1067 | data->currfid, fid); |
@@ -1020,7 +1089,8 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data, unsigned i | |||
1020 | } | 1089 | } |
1021 | 1090 | ||
1022 | /* Take a frequency, and issue the hardware pstate transition command */ | 1091 | /* Take a frequency, and issue the hardware pstate transition command */ |
1023 | static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned int index) | 1092 | static int transition_frequency_pstate(struct powernow_k8_data *data, |
1093 | unsigned int index) | ||
1024 | { | 1094 | { |
1025 | u32 pstate = 0; | 1095 | u32 pstate = 0; |
1026 | int res, i; | 1096 | int res, i; |
@@ -1032,7 +1102,8 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i | |||
1032 | pstate = index & HW_PSTATE_MASK; | 1102 | pstate = index & HW_PSTATE_MASK; |
1033 | if (pstate > data->max_hw_pstate) | 1103 | if (pstate > data->max_hw_pstate) |
1034 | return 0; | 1104 | return 0; |
1035 | freqs.old = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); | 1105 | freqs.old = find_khz_freq_from_pstate(data->powernow_table, |
1106 | data->currpstate); | ||
1036 | freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); | 1107 | freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate); |
1037 | 1108 | ||
1038 | for_each_cpu_mask_nr(i, *(data->available_cores)) { | 1109 | for_each_cpu_mask_nr(i, *(data->available_cores)) { |
@@ -1051,7 +1122,8 @@ static int transition_frequency_pstate(struct powernow_k8_data *data, unsigned i | |||
1051 | } | 1122 | } |
1052 | 1123 | ||
1053 | /* Driver entry point to switch to the target frequency */ | 1124 | /* Driver entry point to switch to the target frequency */ |
1054 | static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsigned relation) | 1125 | static int powernowk8_target(struct cpufreq_policy *pol, |
1126 | unsigned targfreq, unsigned relation) | ||
1055 | { | 1127 | { |
1056 | cpumask_t oldmask; | 1128 | cpumask_t oldmask; |
1057 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1129 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
@@ -1090,14 +1162,18 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1090 | dprintk("targ: curr fid 0x%x, vid 0x%x\n", | 1162 | dprintk("targ: curr fid 0x%x, vid 0x%x\n", |
1091 | data->currfid, data->currvid); | 1163 | data->currfid, data->currvid); |
1092 | 1164 | ||
1093 | if ((checkvid != data->currvid) || (checkfid != data->currfid)) { | 1165 | if ((checkvid != data->currvid) || |
1166 | (checkfid != data->currfid)) { | ||
1094 | printk(KERN_INFO PFX | 1167 | printk(KERN_INFO PFX |
1095 | "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n", | 1168 | "error - out of sync, fix 0x%x 0x%x, " |
1096 | checkfid, data->currfid, checkvid, data->currvid); | 1169 | "vid 0x%x 0x%x\n", |
1170 | checkfid, data->currfid, | ||
1171 | checkvid, data->currvid); | ||
1097 | } | 1172 | } |
1098 | } | 1173 | } |
1099 | 1174 | ||
1100 | if (cpufreq_frequency_table_target(pol, data->powernow_table, targfreq, relation, &newstate)) | 1175 | if (cpufreq_frequency_table_target(pol, data->powernow_table, |
1176 | targfreq, relation, &newstate)) | ||
1101 | goto err_out; | 1177 | goto err_out; |
1102 | 1178 | ||
1103 | mutex_lock(&fidvid_mutex); | 1179 | mutex_lock(&fidvid_mutex); |
@@ -1117,7 +1193,8 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
1117 | mutex_unlock(&fidvid_mutex); | 1193 | mutex_unlock(&fidvid_mutex); |
1118 | 1194 | ||
1119 | if (cpu_family == CPU_HW_PSTATE) | 1195 | if (cpu_family == CPU_HW_PSTATE) |
1120 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, newstate); | 1196 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, |
1197 | newstate); | ||
1121 | else | 1198 | else |
1122 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1199 | pol->cur = find_khz_freq_from_fid(data->currfid); |
1123 | ret = 0; | 1200 | ret = 0; |
@@ -1144,6 +1221,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1144 | struct powernow_k8_data *data; | 1221 | struct powernow_k8_data *data; |
1145 | cpumask_t oldmask; | 1222 | cpumask_t oldmask; |
1146 | int rc; | 1223 | int rc; |
1224 | static int print_once; | ||
1147 | 1225 | ||
1148 | if (!cpu_online(pol->cpu)) | 1226 | if (!cpu_online(pol->cpu)) |
1149 | return -ENODEV; | 1227 | return -ENODEV; |
@@ -1166,33 +1244,31 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1166 | * an UP version, and is deprecated by AMD. | 1244 | * an UP version, and is deprecated by AMD. |
1167 | */ | 1245 | */ |
1168 | if (num_online_cpus() != 1) { | 1246 | if (num_online_cpus() != 1) { |
1169 | #ifndef CONFIG_ACPI_PROCESSOR | 1247 | /* |
1170 | printk(KERN_ERR PFX "ACPI Processor support is required " | 1248 | * Replace this one with print_once as soon as such a |
1171 | "for SMP systems but is absent. Please load the " | 1249 | * thing gets introduced |
1172 | "ACPI Processor module before starting this " | 1250 | */ |
1173 | "driver.\n"); | 1251 | if (!print_once) { |
1174 | #else | 1252 | WARN_ONCE(1, KERN_ERR FW_BUG PFX "Your BIOS " |
1175 | printk(KERN_ERR FW_BUG PFX "Your BIOS does not provide" | 1253 | "does not provide ACPI _PSS objects " |
1176 | " ACPI _PSS objects in a way that Linux " | 1254 | "in a way that Linux understands. " |
1177 | "understands. Please report this to the Linux " | 1255 | "Please report this to the Linux ACPI" |
1178 | "ACPI maintainers and complain to your BIOS " | 1256 | " maintainers and complain to your " |
1179 | "vendor.\n"); | 1257 | "BIOS vendor.\n"); |
1180 | #endif | 1258 | print_once++; |
1181 | kfree(data); | 1259 | } |
1182 | return -ENODEV; | 1260 | goto err_out; |
1183 | } | 1261 | } |
1184 | if (pol->cpu != 0) { | 1262 | if (pol->cpu != 0) { |
1185 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " | 1263 | printk(KERN_ERR FW_BUG PFX "No ACPI _PSS objects for " |
1186 | "CPU other than CPU0. Complain to your BIOS " | 1264 | "CPU other than CPU0. Complain to your BIOS " |
1187 | "vendor.\n"); | 1265 | "vendor.\n"); |
1188 | kfree(data); | 1266 | goto err_out; |
1189 | return -ENODEV; | ||
1190 | } | 1267 | } |
1191 | rc = find_psb_table(data); | 1268 | rc = find_psb_table(data); |
1192 | if (rc) { | 1269 | if (rc) |
1193 | kfree(data); | 1270 | goto err_out; |
1194 | return -ENODEV; | 1271 | |
1195 | } | ||
1196 | /* Take a crude guess here. | 1272 | /* Take a crude guess here. |
1197 | * That guess was in microseconds, so multiply with 1000 */ | 1273 | * That guess was in microseconds, so multiply with 1000 */ |
1198 | pol->cpuinfo.transition_latency = ( | 1274 | pol->cpuinfo.transition_latency = ( |
@@ -1207,16 +1283,16 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1207 | 1283 | ||
1208 | if (smp_processor_id() != pol->cpu) { | 1284 | if (smp_processor_id() != pol->cpu) { |
1209 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); | 1285 | printk(KERN_ERR PFX "limiting to cpu %u failed\n", pol->cpu); |
1210 | goto err_out; | 1286 | goto err_out_unmask; |
1211 | } | 1287 | } |
1212 | 1288 | ||
1213 | if (pending_bit_stuck()) { | 1289 | if (pending_bit_stuck()) { |
1214 | printk(KERN_ERR PFX "failing init, change pending bit set\n"); | 1290 | printk(KERN_ERR PFX "failing init, change pending bit set\n"); |
1215 | goto err_out; | 1291 | goto err_out_unmask; |
1216 | } | 1292 | } |
1217 | 1293 | ||
1218 | if (query_current_values_with_pending_wait(data)) | 1294 | if (query_current_values_with_pending_wait(data)) |
1219 | goto err_out; | 1295 | goto err_out_unmask; |
1220 | 1296 | ||
1221 | if (cpu_family == CPU_OPTERON) | 1297 | if (cpu_family == CPU_OPTERON) |
1222 | fidvid_msr_init(); | 1298 | fidvid_msr_init(); |
@@ -1231,7 +1307,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1231 | data->available_cores = pol->cpus; | 1307 | data->available_cores = pol->cpus; |
1232 | 1308 | ||
1233 | if (cpu_family == CPU_HW_PSTATE) | 1309 | if (cpu_family == CPU_HW_PSTATE) |
1234 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, data->currpstate); | 1310 | pol->cur = find_khz_freq_from_pstate(data->powernow_table, |
1311 | data->currpstate); | ||
1235 | else | 1312 | else |
1236 | pol->cur = find_khz_freq_from_fid(data->currfid); | 1313 | pol->cur = find_khz_freq_from_fid(data->currfid); |
1237 | dprintk("policy current frequency %d kHz\n", pol->cur); | 1314 | dprintk("policy current frequency %d kHz\n", pol->cur); |
@@ -1248,7 +1325,8 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1248 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); | 1325 | cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); |
1249 | 1326 | ||
1250 | if (cpu_family == CPU_HW_PSTATE) | 1327 | if (cpu_family == CPU_HW_PSTATE) |
1251 | dprintk("cpu_init done, current pstate 0x%x\n", data->currpstate); | 1328 | dprintk("cpu_init done, current pstate 0x%x\n", |
1329 | data->currpstate); | ||
1252 | else | 1330 | else |
1253 | dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", | 1331 | dprintk("cpu_init done, current fid 0x%x, vid 0x%x\n", |
1254 | data->currfid, data->currvid); | 1332 | data->currfid, data->currvid); |
@@ -1257,15 +1335,16 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) | |||
1257 | 1335 | ||
1258 | return 0; | 1336 | return 0; |
1259 | 1337 | ||
1260 | err_out: | 1338 | err_out_unmask: |
1261 | set_cpus_allowed_ptr(current, &oldmask); | 1339 | set_cpus_allowed_ptr(current, &oldmask); |
1262 | powernow_k8_cpu_exit_acpi(data); | 1340 | powernow_k8_cpu_exit_acpi(data); |
1263 | 1341 | ||
1342 | err_out: | ||
1264 | kfree(data); | 1343 | kfree(data); |
1265 | return -ENODEV; | 1344 | return -ENODEV; |
1266 | } | 1345 | } |
1267 | 1346 | ||
1268 | static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol) | 1347 | static int __devexit powernowk8_cpu_exit(struct cpufreq_policy *pol) |
1269 | { | 1348 | { |
1270 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); | 1349 | struct powernow_k8_data *data = per_cpu(powernow_data, pol->cpu); |
1271 | 1350 | ||
@@ -1282,7 +1361,7 @@ static int __devexit powernowk8_cpu_exit (struct cpufreq_policy *pol) | |||
1282 | return 0; | 1361 | return 0; |
1283 | } | 1362 | } |
1284 | 1363 | ||
1285 | static unsigned int powernowk8_get (unsigned int cpu) | 1364 | static unsigned int powernowk8_get(unsigned int cpu) |
1286 | { | 1365 | { |
1287 | struct powernow_k8_data *data; | 1366 | struct powernow_k8_data *data; |
1288 | cpumask_t oldmask = current->cpus_allowed; | 1367 | cpumask_t oldmask = current->cpus_allowed; |
@@ -1318,7 +1397,7 @@ out: | |||
1318 | return khz; | 1397 | return khz; |
1319 | } | 1398 | } |
1320 | 1399 | ||
1321 | static struct freq_attr* powernow_k8_attr[] = { | 1400 | static struct freq_attr *powernow_k8_attr[] = { |
1322 | &cpufreq_freq_attr_scaling_available_freqs, | 1401 | &cpufreq_freq_attr_scaling_available_freqs, |
1323 | NULL, | 1402 | NULL, |
1324 | }; | 1403 | }; |
@@ -1363,7 +1442,8 @@ static void __exit powernowk8_exit(void) | |||
1363 | cpufreq_unregister_driver(&cpufreq_amd64_driver); | 1442 | cpufreq_unregister_driver(&cpufreq_amd64_driver); |
1364 | } | 1443 | } |
1365 | 1444 | ||
1366 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and Mark Langsdorf <mark.langsdorf@amd.com>"); | 1445 | MODULE_AUTHOR("Paul Devriendt <paul.devriendt@amd.com> and " |
1446 | "Mark Langsdorf <mark.langsdorf@amd.com>"); | ||
1367 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); | 1447 | MODULE_DESCRIPTION("AMD Athlon 64 and Opteron processor frequency driver."); |
1368 | MODULE_LICENSE("GPL"); | 1448 | MODULE_LICENSE("GPL"); |
1369 | 1449 | ||