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