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