powernow-k7: Fix CPU family number
[linux-block.git] / drivers / cpufreq / powernow-k7.c
CommitLineData
1da177e4
LT
1/*
2 * AMD K7 Powernow driver.
f4432c5c 3 * (C) 2003 Dave Jones on behalf of SuSE Labs.
1da177e4
LT
4 * (C) 2003-2004 Dave Jones <davej@redhat.com>
5 *
6 * Licensed under the terms of the GNU GPL License version 2.
7 * Based upon datasheets & sample CPUs kindly provided by AMD.
8 *
b9e7638a
DJ
9 * Errata 5:
10 * CPU may fail to execute a FID/VID change in presence of interrupt.
11 * - We cli/sti on stepping A0 CPUs around the FID/VID transition.
12 * Errata 15:
13 * CPU with half frequency multipliers may hang upon wakeup from disconnect.
14 * - We disable half multipliers if ACPI is used on A0 stepping CPUs.
1da177e4
LT
15 */
16
1da177e4
LT
17#include <linux/kernel.h>
18#include <linux/module.h>
19#include <linux/moduleparam.h>
20#include <linux/init.h>
21#include <linux/cpufreq.h>
22#include <linux/slab.h>
23#include <linux/string.h>
24#include <linux/dmi.h>
b9e7638a
DJ
25#include <linux/timex.h>
26#include <linux/io.h>
1da177e4 27
b9e7638a 28#include <asm/timer.h> /* Needed for recalibrate_cpu_khz() */
1da177e4 29#include <asm/msr.h>
1da177e4 30#include <asm/system.h>
fa8031ae 31#include <asm/cpu_device_id.h>
1da177e4
LT
32
33#ifdef CONFIG_X86_POWERNOW_K7_ACPI
34#include <linux/acpi.h>
35#include <acpi/processor.h>
36#endif
37
38#include "powernow-k7.h"
39
40#define PFX "powernow: "
41
42
43struct psb_s {
44 u8 signature[10];
45 u8 tableversion;
46 u8 flags;
47 u16 settlingtime;
48 u8 reserved1;
49 u8 numpst;
50};
51
52struct pst_s {
53 u32 cpuid;
54 u8 fsbspeed;
55 u8 maxfid;
56 u8 startvid;
57 u8 numpstates;
58};
59
60#ifdef CONFIG_X86_POWERNOW_K7_ACPI
61union powernow_acpi_control_t {
62 struct {
63 unsigned long fid:5,
b9e7638a
DJ
64 vid:5,
65 sgtc:20,
66 res1:2;
1da177e4
LT
67 } bits;
68 unsigned long val;
69};
70#endif
71
1da177e4 72/* divide by 1000 to get VCore voltage in V. */
bd5ab26a 73static const int mobile_vid_table[32] = {
1da177e4
LT
74 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,
75 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0,
76 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,
77 1075, 1050, 1025, 1000, 975, 950, 925, 0,
78};
1da177e4
LT
79
80/* divide by 10 to get FID. */
bd5ab26a 81static const int fid_codes[32] = {
1da177e4
LT
82 110, 115, 120, 125, 50, 55, 60, 65,
83 70, 75, 80, 85, 90, 95, 100, 105,
84 30, 190, 40, 200, 130, 135, 140, 210,
85 150, 225, 160, 165, 170, 180, -1, -1,
86};
87
88/* This parameter is used in order to force ACPI instead of legacy method for
89 * configuration purpose.
90 */
91
92static int acpi_force;
93
94static struct cpufreq_frequency_table *powernow_table;
95
96static unsigned int can_scale_bus;
97static unsigned int can_scale_vid;
fff78ad5 98static unsigned int minimum_speed = -1;
1da177e4
LT
99static unsigned int maximum_speed;
100static unsigned int number_scales;
101static unsigned int fsb;
102static unsigned int latency;
103static char have_a0;
104
1da177e4
LT
105static int check_fsb(unsigned int fsbspeed)
106{
107 int delta;
108 unsigned int f = fsb / 1000;
109
110 delta = (fsbspeed > f) ? fsbspeed - f : f - fsbspeed;
b9e7638a 111 return delta < 5;
1da177e4
LT
112}
113
fa8031ae 114static const struct x86_cpu_id powernow_k7_cpuids[] = {
30bcfff9 115 { X86_VENDOR_AMD, 6, },
fa8031ae
AK
116 {}
117};
118MODULE_DEVICE_TABLE(x86cpu, powernow_k7_cpuids);
119
1da177e4
LT
120static int check_powernow(void)
121{
92cb7612 122 struct cpuinfo_x86 *c = &cpu_data(0);
1da177e4
LT
123 unsigned int maxei, eax, ebx, ecx, edx;
124
fa8031ae 125 if (!x86_match_cpu(powernow_k7_cpuids))
1da177e4 126 return 0;
1da177e4
LT
127
128 /* Get maximum capabilities */
b9e7638a 129 maxei = cpuid_eax(0x80000000);
1da177e4
LT
130 if (maxei < 0x80000007) { /* Any powernow info ? */
131#ifdef MODULE
b9e7638a 132 printk(KERN_INFO PFX "No powernow capabilities detected\n");
1da177e4
LT
133#endif
134 return 0;
135 }
136
137 if ((c->x86_model == 6) && (c->x86_mask == 0)) {
b9e7638a
DJ
138 printk(KERN_INFO PFX "K7 660[A0] core detected, "
139 "enabling errata workarounds\n");
1da177e4
LT
140 have_a0 = 1;
141 }
142
143 cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
144
145 /* Check we can actually do something before we say anything.*/
146 if (!(edx & (1 << 1 | 1 << 2)))
147 return 0;
148
b9e7638a 149 printk(KERN_INFO PFX "PowerNOW! Technology present. Can scale: ");
1da177e4
LT
150
151 if (edx & 1 << 1) {
b9e7638a
DJ
152 printk("frequency");
153 can_scale_bus = 1;
1da177e4
LT
154 }
155
156 if ((edx & (1 << 1 | 1 << 2)) == 0x6)
b9e7638a 157 printk(" and ");
1da177e4
LT
158
159 if (edx & 1 << 2) {
b9e7638a
DJ
160 printk("voltage");
161 can_scale_vid = 1;
1da177e4
LT
162 }
163
b9e7638a 164 printk(".\n");
1da177e4
LT
165 return 1;
166}
167
d38e73e8 168#ifdef CONFIG_X86_POWERNOW_K7_ACPI
b9e7638a
DJ
169static void invalidate_entry(unsigned int entry)
170{
171 powernow_table[entry].frequency = CPUFREQ_ENTRY_INVALID;
172}
d38e73e8 173#endif
1da177e4 174
b9e7638a 175static int get_ranges(unsigned char *pst)
1da177e4
LT
176{
177 unsigned int j;
178 unsigned int speed;
179 u8 fid, vid;
180
b9e7638a
DJ
181 powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
182 (number_scales + 1)), GFP_KERNEL);
1da177e4
LT
183 if (!powernow_table)
184 return -ENOMEM;
1da177e4 185
b9e7638a 186 for (j = 0 ; j < number_scales; j++) {
1da177e4
LT
187 fid = *pst++;
188
189 powernow_table[j].frequency = (fsb * fid_codes[fid]) / 10;
190 powernow_table[j].index = fid; /* lower 8 bits */
191
192 speed = powernow_table[j].frequency;
193
b9e7638a 194 if ((fid_codes[fid] % 10) == 5) {
1da177e4
LT
195#ifdef CONFIG_X86_POWERNOW_K7_ACPI
196 if (have_a0 == 1)
b9e7638a 197 invalidate_entry(j);
1da177e4
LT
198#endif
199 }
200
201 if (speed < minimum_speed)
202 minimum_speed = speed;
203 if (speed > maximum_speed)
204 maximum_speed = speed;
205
206 vid = *pst++;
207 powernow_table[j].index |= (vid << 8); /* upper 8 bits */
208
2d06d8c4 209 pr_debug(" FID: 0x%x (%d.%dx [%dMHz]) "
32ee8c3e
DJ
210 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
211 fid_codes[fid] % 10, speed/1000, vid,
1da177e4
LT
212 mobile_vid_table[vid]/1000,
213 mobile_vid_table[vid]%1000);
214 }
215 powernow_table[number_scales].frequency = CPUFREQ_TABLE_END;
216 powernow_table[number_scales].index = 0;
217
218 return 0;
219}
220
221
222static void change_FID(int fid)
223{
224 union msr_fidvidctl fidvidctl;
225
b9e7638a 226 rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
1da177e4
LT
227 if (fidvidctl.bits.FID != fid) {
228 fidvidctl.bits.SGTC = latency;
229 fidvidctl.bits.FID = fid;
230 fidvidctl.bits.VIDC = 0;
231 fidvidctl.bits.FIDC = 1;
b9e7638a 232 wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
1da177e4
LT
233 }
234}
235
236
237static void change_VID(int vid)
238{
239 union msr_fidvidctl fidvidctl;
240
b9e7638a 241 rdmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
1da177e4
LT
242 if (fidvidctl.bits.VID != vid) {
243 fidvidctl.bits.SGTC = latency;
244 fidvidctl.bits.VID = vid;
245 fidvidctl.bits.FIDC = 0;
246 fidvidctl.bits.VIDC = 1;
b9e7638a 247 wrmsrl(MSR_K7_FID_VID_CTL, fidvidctl.val);
1da177e4
LT
248 }
249}
250
251
b9e7638a 252static void change_speed(unsigned int index)
1da177e4
LT
253{
254 u8 fid, vid;
255 struct cpufreq_freqs freqs;
256 union msr_fidvidstatus fidvidstatus;
257 int cfid;
258
259 /* fid are the lower 8 bits of the index we stored into
260 * the cpufreq frequency table in powernow_decode_bios,
261 * vid are the upper 8 bits.
262 */
263
264 fid = powernow_table[index].index & 0xFF;
265 vid = (powernow_table[index].index & 0xFF00) >> 8;
266
267 freqs.cpu = 0;
268
b9e7638a 269 rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
1da177e4
LT
270 cfid = fidvidstatus.bits.CFID;
271 freqs.old = fsb * fid_codes[cfid] / 10;
272
273 freqs.new = powernow_table[index].frequency;
274
275 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
276
277 /* Now do the magic poking into the MSRs. */
278
279 if (have_a0 == 1) /* A0 errata 5 */
280 local_irq_disable();
281
282 if (freqs.old > freqs.new) {
283 /* Going down, so change FID first */
284 change_FID(fid);
285 change_VID(vid);
286 } else {
287 /* Going up, so change VID first */
288 change_VID(vid);
289 change_FID(fid);
290 }
291
292
293 if (have_a0 == 1)
294 local_irq_enable();
295
296 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
297}
298
299
300#ifdef CONFIG_X86_POWERNOW_K7_ACPI
301
302static struct acpi_processor_performance *acpi_processor_perf;
303
304static int powernow_acpi_init(void)
305{
306 int i;
307 int retval = 0;
308 union powernow_acpi_control_t pc;
309
310 if (acpi_processor_perf != NULL && powernow_table != NULL) {
311 retval = -EINVAL;
312 goto err0;
313 }
314
bfdc708d 315 acpi_processor_perf = kzalloc(sizeof(struct acpi_processor_performance),
1da177e4 316 GFP_KERNEL);
1da177e4
LT
317 if (!acpi_processor_perf) {
318 retval = -ENOMEM;
319 goto err0;
320 }
321
eaa95840 322 if (!zalloc_cpumask_var(&acpi_processor_perf->shared_cpu_map,
2fdf66b4
RR
323 GFP_KERNEL)) {
324 retval = -ENOMEM;
325 goto err05;
326 }
327
1da177e4
LT
328 if (acpi_processor_register_performance(acpi_processor_perf, 0)) {
329 retval = -EIO;
330 goto err1;
331 }
332
b9e7638a
DJ
333 if (acpi_processor_perf->control_register.space_id !=
334 ACPI_ADR_SPACE_FIXED_HARDWARE) {
1da177e4
LT
335 retval = -ENODEV;
336 goto err2;
337 }
338
b9e7638a
DJ
339 if (acpi_processor_perf->status_register.space_id !=
340 ACPI_ADR_SPACE_FIXED_HARDWARE) {
1da177e4
LT
341 retval = -ENODEV;
342 goto err2;
343 }
344
345 number_scales = acpi_processor_perf->state_count;
346
347 if (number_scales < 2) {
348 retval = -ENODEV;
349 goto err2;
350 }
351
b9e7638a
DJ
352 powernow_table = kzalloc((sizeof(struct cpufreq_frequency_table) *
353 (number_scales + 1)), GFP_KERNEL);
1da177e4
LT
354 if (!powernow_table) {
355 retval = -ENOMEM;
356 goto err2;
357 }
358
1da177e4
LT
359 pc.val = (unsigned long) acpi_processor_perf->states[0].control;
360 for (i = 0; i < number_scales; i++) {
361 u8 fid, vid;
dc2585eb
DD
362 struct acpi_processor_px *state =
363 &acpi_processor_perf->states[i];
364 unsigned int speed, speed_mhz;
1da177e4 365
dc2585eb 366 pc.val = (unsigned long) state->control;
2d06d8c4 367 pr_debug("acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
1da177e4 368 i,
dc2585eb
DD
369 (u32) state->core_frequency,
370 (u32) state->power,
371 (u32) state->transition_latency,
372 (u32) state->control,
1da177e4
LT
373 pc.bits.sgtc);
374
375 vid = pc.bits.vid;
376 fid = pc.bits.fid;
377
378 powernow_table[i].frequency = fsb * fid_codes[fid] / 10;
379 powernow_table[i].index = fid; /* lower 8 bits */
380 powernow_table[i].index |= (vid << 8); /* upper 8 bits */
381
382 speed = powernow_table[i].frequency;
dc2585eb
DD
383 speed_mhz = speed / 1000;
384
385 /* processor_perflib will multiply the MHz value by 1000 to
386 * get a KHz value (e.g. 1266000). However, powernow-k7 works
387 * with true KHz values (e.g. 1266768). To ensure that all
388 * powernow frequencies are available, we must ensure that
389 * ACPI doesn't restrict them, so we round up the MHz value
390 * to ensure that perflib's computed KHz value is greater than
391 * or equal to powernow's KHz value.
392 */
393 if (speed % 1000 > 0)
394 speed_mhz++;
1da177e4 395
b9e7638a 396 if ((fid_codes[fid] % 10) == 5) {
1da177e4 397 if (have_a0 == 1)
b9e7638a 398 invalidate_entry(i);
1da177e4
LT
399 }
400
2d06d8c4 401 pr_debug(" FID: 0x%x (%d.%dx [%dMHz]) "
32ee8c3e 402 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
dc2585eb 403 fid_codes[fid] % 10, speed_mhz, vid,
1da177e4
LT
404 mobile_vid_table[vid]/1000,
405 mobile_vid_table[vid]%1000);
406
dc2585eb
DD
407 if (state->core_frequency != speed_mhz) {
408 state->core_frequency = speed_mhz;
2d06d8c4 409 pr_debug(" Corrected ACPI frequency to %d\n",
dc2585eb
DD
410 speed_mhz);
411 }
412
1da177e4
LT
413 if (latency < pc.bits.sgtc)
414 latency = pc.bits.sgtc;
415
416 if (speed < minimum_speed)
417 minimum_speed = speed;
418 if (speed > maximum_speed)
419 maximum_speed = speed;
420 }
421
422 powernow_table[i].frequency = CPUFREQ_TABLE_END;
423 powernow_table[i].index = 0;
424
425 /* notify BIOS that we exist */
426 acpi_processor_notify_smm(THIS_MODULE);
427
428 return 0;
429
430err2:
431 acpi_processor_unregister_performance(acpi_processor_perf, 0);
432err1:
2fdf66b4
RR
433 free_cpumask_var(acpi_processor_perf->shared_cpu_map);
434err05:
1da177e4
LT
435 kfree(acpi_processor_perf);
436err0:
b9e7638a
DJ
437 printk(KERN_WARNING PFX "ACPI perflib can not be used on "
438 "this platform\n");
1da177e4
LT
439 acpi_processor_perf = NULL;
440 return retval;
441}
442#else
443static int powernow_acpi_init(void)
444{
445 printk(KERN_INFO PFX "no support for ACPI processor found."
446 " Please recompile your kernel with ACPI processor\n");
447 return -EINVAL;
448}
449#endif
450
b9e7638a
DJ
451static void print_pst_entry(struct pst_s *pst, unsigned int j)
452{
2d06d8c4
DB
453 pr_debug("PST:%d (@%p)\n", j, pst);
454 pr_debug(" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n",
b9e7638a
DJ
455 pst->cpuid, pst->fsbspeed, pst->maxfid, pst->startvid);
456}
457
458static int powernow_decode_bios(int maxfid, int startvid)
1da177e4
LT
459{
460 struct psb_s *psb;
461 struct pst_s *pst;
462 unsigned int i, j;
463 unsigned char *p;
464 unsigned int etuple;
465 unsigned int ret;
466
467 etuple = cpuid_eax(0x80000001);
468
b9e7638a 469 for (i = 0xC0000; i < 0xffff0 ; i += 16) {
1da177e4
LT
470
471 p = phys_to_virt(i);
472
b9e7638a 473 if (memcmp(p, "AMDK7PNOW!", 10) == 0) {
2d06d8c4 474 pr_debug("Found PSB header at %p\n", p);
1da177e4 475 psb = (struct psb_s *) p;
2d06d8c4 476 pr_debug("Table version: 0x%x\n", psb->tableversion);
1da177e4 477 if (psb->tableversion != 0x12) {
b9e7638a
DJ
478 printk(KERN_INFO PFX "Sorry, only v1.2 tables"
479 " supported right now\n");
1da177e4
LT
480 return -ENODEV;
481 }
482
2d06d8c4 483 pr_debug("Flags: 0x%x\n", psb->flags);
b9e7638a 484 if ((psb->flags & 1) == 0)
2d06d8c4 485 pr_debug("Mobile voltage regulator\n");
b9e7638a 486 else
2d06d8c4 487 pr_debug("Desktop voltage regulator\n");
1da177e4
LT
488
489 latency = psb->settlingtime;
490 if (latency < 100) {
b9e7638a
DJ
491 printk(KERN_INFO PFX "BIOS set settling time "
492 "to %d microseconds. "
493 "Should be at least 100. "
494 "Correcting.\n", latency);
1da177e4
LT
495 latency = 100;
496 }
2d06d8c4 497 pr_debug("Settling Time: %d microseconds.\n",
b9e7638a 498 psb->settlingtime);
2d06d8c4 499 pr_debug("Has %d PST tables. (Only dumping ones "
b9e7638a
DJ
500 "relevant to this CPU).\n",
501 psb->numpst);
1da177e4 502
b9e7638a 503 p += sizeof(struct psb_s);
1da177e4
LT
504
505 pst = (struct pst_s *) p;
506
b9e7638a 507 for (j = 0; j < psb->numpst; j++) {
1da177e4
LT
508 pst = (struct pst_s *) p;
509 number_scales = pst->numpstates;
510
b9e7638a
DJ
511 if ((etuple == pst->cpuid) &&
512 check_fsb(pst->fsbspeed) &&
513 (maxfid == pst->maxfid) &&
514 (startvid == pst->startvid)) {
515 print_pst_entry(pst, j);
516 p = (char *)pst + sizeof(struct pst_s);
517 ret = get_ranges(p);
1da177e4 518 return ret;
1da177e4 519 } else {
8cbe0169 520 unsigned int k;
b9e7638a
DJ
521 p = (char *)pst + sizeof(struct pst_s);
522 for (k = 0; k < number_scales; k++)
523 p += 2;
1da177e4
LT
524 }
525 }
b9e7638a
DJ
526 printk(KERN_INFO PFX "No PST tables match this cpuid "
527 "(0x%x)\n", etuple);
528 printk(KERN_INFO PFX "This is indicative of a broken "
529 "BIOS.\n");
1da177e4
LT
530
531 return -EINVAL;
532 }
533 p++;
534 }
535
536 return -ENODEV;
537}
538
539
b9e7638a 540static int powernow_target(struct cpufreq_policy *policy,
1da177e4
LT
541 unsigned int target_freq,
542 unsigned int relation)
543{
544 unsigned int newstate;
545
b9e7638a
DJ
546 if (cpufreq_frequency_table_target(policy, powernow_table, target_freq,
547 relation, &newstate))
1da177e4
LT
548 return -EINVAL;
549
550 change_speed(newstate);
551
552 return 0;
553}
554
555
b9e7638a 556static int powernow_verify(struct cpufreq_policy *policy)
1da177e4
LT
557{
558 return cpufreq_frequency_table_verify(policy, powernow_table);
559}
560
561/*
562 * We use the fact that the bus frequency is somehow
563 * a multiple of 100000/3 khz, then we compute sgtc according
564 * to this multiple.
565 * That way, we match more how AMD thinks all of that work.
566 * We will then get the same kind of behaviour already tested under
567 * the "well-known" other OS.
568 */
307069cf 569static int __cpuinit fixup_sgtc(void)
1da177e4
LT
570{
571 unsigned int sgtc;
572 unsigned int m;
573
574 m = fsb / 3333;
575 if ((m % 10) >= 5)
576 m += 5;
577
578 m /= 10;
579
580 sgtc = 100 * m * latency;
581 sgtc = sgtc / 3;
582 if (sgtc > 0xfffff) {
583 printk(KERN_WARNING PFX "SGTC too large %d\n", sgtc);
584 sgtc = 0xfffff;
585 }
586 return sgtc;
587}
588
589static unsigned int powernow_get(unsigned int cpu)
590{
591 union msr_fidvidstatus fidvidstatus;
592 unsigned int cfid;
593
594 if (cpu)
595 return 0;
b9e7638a 596 rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
1da177e4
LT
597 cfid = fidvidstatus.bits.CFID;
598
b9e7638a 599 return fsb * fid_codes[cfid] / 10;
1da177e4
LT
600}
601
602
307069cf 603static int __cpuinit acer_cpufreq_pst(const struct dmi_system_id *d)
1da177e4 604{
b9e7638a
DJ
605 printk(KERN_WARNING PFX
606 "%s laptop with broken PST tables in BIOS detected.\n",
607 d->ident);
608 printk(KERN_WARNING PFX
609 "You need to downgrade to 3A21 (09/09/2002), or try a newer "
610 "BIOS than 3A71 (01/20/2003)\n");
611 printk(KERN_WARNING PFX
612 "cpufreq scaling has been disabled as a result of this.\n");
1da177e4
LT
613 return 0;
614}
615
616/*
617 * Some Athlon laptops have really fucked PST tables.
618 * A BIOS update is all that can save them.
619 * Mention this, and disable cpufreq.
620 */
307069cf 621static struct dmi_system_id __cpuinitdata powernow_dmi_table[] = {
1da177e4
LT
622 {
623 .callback = acer_cpufreq_pst,
624 .ident = "Acer Aspire",
625 .matches = {
626 DMI_MATCH(DMI_SYS_VENDOR, "Insyde Software"),
627 DMI_MATCH(DMI_BIOS_VERSION, "3A71"),
628 },
629 },
630 { }
631};
632
307069cf 633static int __cpuinit powernow_cpu_init(struct cpufreq_policy *policy)
1da177e4
LT
634{
635 union msr_fidvidstatus fidvidstatus;
636 int result;
637
638 if (policy->cpu != 0)
639 return -ENODEV;
640
b9e7638a 641 rdmsrl(MSR_K7_FID_VID_STATUS, fidvidstatus.val);
1da177e4 642
436fe7b8 643 recalibrate_cpu_khz();
91350ed4
DJ
644
645 fsb = (10 * cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
1da177e4
LT
646 if (!fsb) {
647 printk(KERN_WARNING PFX "can not determine bus frequency\n");
648 return -EINVAL;
649 }
2d06d8c4 650 pr_debug("FSB: %3dMHz\n", fsb/1000);
1da177e4
LT
651
652 if (dmi_check_system(powernow_dmi_table) || acpi_force) {
b9e7638a
DJ
653 printk(KERN_INFO PFX "PSB/PST known to be broken. "
654 "Trying ACPI instead\n");
1da177e4
LT
655 result = powernow_acpi_init();
656 } else {
b9e7638a
DJ
657 result = powernow_decode_bios(fidvidstatus.bits.MFID,
658 fidvidstatus.bits.SVID);
1da177e4 659 if (result) {
b9e7638a 660 printk(KERN_INFO PFX "Trying ACPI perflib\n");
1da177e4
LT
661 maximum_speed = 0;
662 minimum_speed = -1;
663 latency = 0;
664 result = powernow_acpi_init();
665 if (result) {
b9e7638a
DJ
666 printk(KERN_INFO PFX
667 "ACPI and legacy methods failed\n");
1da177e4
LT
668 }
669 } else {
670 /* SGTC use the bus clock as timer */
671 latency = fixup_sgtc();
672 printk(KERN_INFO PFX "SGTC: %d\n", latency);
673 }
674 }
675
676 if (result)
677 return result;
678
b9e7638a 679 printk(KERN_INFO PFX "Minimum speed %d MHz. Maximum speed %d MHz.\n",
1da177e4
LT
680 minimum_speed/1000, maximum_speed/1000);
681
b9e7638a
DJ
682 policy->cpuinfo.transition_latency =
683 cpufreq_scale(2000000UL, fsb, latency);
1da177e4
LT
684
685 policy->cur = powernow_get(0);
686
687 cpufreq_frequency_table_get_attr(powernow_table, policy->cpu);
688
689 return cpufreq_frequency_table_cpuinfo(policy, powernow_table);
690}
691
b9e7638a
DJ
692static int powernow_cpu_exit(struct cpufreq_policy *policy)
693{
1da177e4
LT
694 cpufreq_frequency_table_put_attr(policy->cpu);
695
696#ifdef CONFIG_X86_POWERNOW_K7_ACPI
697 if (acpi_processor_perf) {
698 acpi_processor_unregister_performance(acpi_processor_perf, 0);
2fdf66b4 699 free_cpumask_var(acpi_processor_perf->shared_cpu_map);
1da177e4
LT
700 kfree(acpi_processor_perf);
701 }
702#endif
703
4ae6673e 704 kfree(powernow_table);
1da177e4
LT
705 return 0;
706}
707
b9e7638a 708static struct freq_attr *powernow_table_attr[] = {
1da177e4
LT
709 &cpufreq_freq_attr_scaling_available_freqs,
710 NULL,
711};
712
221dee28 713static struct cpufreq_driver powernow_driver = {
e2f74f35
TR
714 .verify = powernow_verify,
715 .target = powernow_target,
716 .get = powernow_get,
717#ifdef CONFIG_X86_POWERNOW_K7_ACPI
718 .bios_limit = acpi_processor_get_bios_limit,
719#endif
720 .init = powernow_cpu_init,
721 .exit = powernow_cpu_exit,
722 .name = "powernow-k7",
723 .owner = THIS_MODULE,
724 .attr = powernow_table_attr,
1da177e4
LT
725};
726
b9e7638a 727static int __init powernow_init(void)
1da177e4 728{
b9e7638a 729 if (check_powernow() == 0)
1da177e4
LT
730 return -ENODEV;
731 return cpufreq_register_driver(&powernow_driver);
732}
733
734
b9e7638a 735static void __exit powernow_exit(void)
1da177e4
LT
736{
737 cpufreq_unregister_driver(&powernow_driver);
738}
739
740module_param(acpi_force, int, 0444);
741MODULE_PARM_DESC(acpi_force, "Force ACPI to be used.");
742
b9e7638a
DJ
743MODULE_AUTHOR("Dave Jones <davej@redhat.com>");
744MODULE_DESCRIPTION("Powernow driver for AMD K7 processors.");
745MODULE_LICENSE("GPL");
1da177e4
LT
746
747late_initcall(powernow_init);
748module_exit(powernow_exit);
749