17 #include <linux/kernel.h>
18 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/string.h>
25 #include <linux/timex.h>
28 #include <asm/timer.h>
32 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
39 #define PFX "powernow: "
59 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
60 union powernow_acpi_control_t {
72 static const int mobile_vid_table[32] = {
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,
80 static const int fid_codes[32] = {
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,
91 static int acpi_force;
95 static unsigned int can_scale_bus;
96 static unsigned int can_scale_vid;
97 static unsigned int minimum_speed = -1;
98 static unsigned int maximum_speed;
99 static unsigned int number_scales;
100 static unsigned int fsb;
104 static int check_fsb(
unsigned int fsbspeed)
107 unsigned int f = fsb / 1000;
109 delta = (fsbspeed >
f) ? fsbspeed - f : f - fsbspeed;
113 static const struct x86_cpu_id powernow_k7_cpuids[] = {
119 static int check_powernow(
void)
122 unsigned int maxei, eax,
ebx,
ecx, edx;
128 maxei = cpuid_eax(0x80000000);
129 if (maxei < 0x80000007) {
138 "enabling errata workarounds\n");
142 cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
145 if (!(edx & (1 << 1 | 1 << 2)))
155 if ((edx & (1 << 1 | 1 << 2)) == 0x6)
167 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
168 static void invalidate_entry(
unsigned int entry)
174 static int get_ranges(
unsigned char *pst)
185 for (j = 0 ; j < number_scales; j++) {
193 if ((fid_codes[fid] % 10) == 5) {
194 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
200 if (speed < minimum_speed)
201 minimum_speed = speed;
202 if (speed > maximum_speed)
203 maximum_speed = speed;
206 powernow_table[
j].
index |= (vid << 8);
208 pr_debug(
" FID: 0x%x (%d.%dx [%dMHz]) "
209 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
210 fid_codes[fid] % 10, speed/1000, vid,
211 mobile_vid_table[vid]/1000,
212 mobile_vid_table[vid]%1000);
215 powernow_table[number_scales].
index = 0;
221 static void change_FID(
int fid)
226 if (fidvidctl.bits.FID != fid) {
228 fidvidctl.bits.FID =
fid;
229 fidvidctl.bits.VIDC = 0;
230 fidvidctl.bits.FIDC = 1;
236 static void change_VID(
int vid)
241 if (fidvidctl.bits.VID != vid) {
243 fidvidctl.bits.VID =
vid;
244 fidvidctl.bits.FIDC = 0;
245 fidvidctl.bits.VIDC = 1;
251 static void change_speed(
unsigned int index)
264 vid = (powernow_table[
index].
index & 0xFF00) >> 8;
269 cfid = fidvidstatus.bits.CFID;
270 freqs.old = fsb * fid_codes[cfid] / 10;
281 if (freqs.old > freqs.new) {
299 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
303 static int powernow_acpi_init(
void)
307 union powernow_acpi_control_t
pc;
309 if (acpi_processor_perf !=
NULL && powernow_table !=
NULL) {
316 if (!acpi_processor_perf) {
346 if (number_scales < 2) {
353 if (!powernow_table) {
358 pc.val = (
unsigned long) acpi_processor_perf->
states[0].control;
359 for (i = 0; i < number_scales; i++) {
362 &acpi_processor_perf->
states[
i];
363 unsigned int speed, speed_mhz;
366 pr_debug(
"acpi: P%d: %d MHz %d mW %d uS control %08x SGTC %d\n",
379 powernow_table[
i].
index |= (vid << 8);
382 speed_mhz = speed / 1000;
392 if (speed % 1000 > 0)
395 if ((fid_codes[fid] % 10) == 5) {
400 pr_debug(
" FID: 0x%x (%d.%dx [%dMHz]) "
401 "VID: 0x%x (%d.%03dV)\n", fid, fid_codes[fid] / 10,
402 fid_codes[fid] % 10, speed_mhz, vid,
403 mobile_vid_table[vid]/1000,
404 mobile_vid_table[vid]%1000);
408 pr_debug(
" Corrected ACPI frequency to %d\n",
415 if (speed < minimum_speed)
416 minimum_speed = speed;
417 if (speed > maximum_speed)
418 maximum_speed = speed;
422 powernow_table[
i].
index = 0;
434 kfree(acpi_processor_perf);
438 acpi_processor_perf =
NULL;
442 static int powernow_acpi_init(
void)
445 " Please recompile your kernel with ACPI processor\n");
450 static void print_pst_entry(
struct pst_s *pst,
unsigned int j)
453 pr_debug(
" cpuid: 0x%x fsb: %d maxFID: 0x%x startvid: 0x%x\n",
457 static int powernow_decode_bios(
int maxfid,
int startvid)
466 etuple = cpuid_eax(0x80000001);
468 for (i = 0xC0000; i < 0xffff0 ; i += 16) {
472 if (
memcmp(p,
"AMDK7PNOW!", 10) == 0) {
473 pr_debug(
"Found PSB header at %p\n", p);
474 psb = (
struct psb_s *) p;
478 " supported right now\n");
483 if ((psb->
flags & 1) == 0)
484 pr_debug(
"Mobile voltage regulator\n");
486 pr_debug(
"Desktop voltage regulator\n");
491 "to %d microseconds. "
492 "Should be at least 100. "
496 pr_debug(
"Settling Time: %d microseconds.\n",
498 pr_debug(
"Has %d PST tables. (Only dumping ones "
499 "relevant to this CPU).\n",
502 p +=
sizeof(
struct psb_s);
504 pst = (
struct pst_s *) p;
506 for (j = 0; j < psb->
numpst; j++) {
507 pst = (
struct pst_s *) p;
510 if ((etuple == pst->
cpuid) &&
512 (maxfid == pst->
maxfid) &&
514 print_pst_entry(pst, j);
515 p = (
char *)pst +
sizeof(
struct pst_s);
520 p = (
char *)pst +
sizeof(
struct pst_s);
521 for (k = 0; k < number_scales; k++)
540 unsigned int target_freq,
541 unsigned int relation)
543 unsigned int newstate;
546 relation, &newstate))
549 change_speed(newstate);
581 if (sgtc > 0xfffff) {
588 static unsigned int powernow_get(
unsigned int cpu)
596 cfid = fidvidstatus.bits.CFID;
598 return fsb * fid_codes[cfid] / 10;
605 "%s laptop with broken PST tables in BIOS detected.\n",
608 "You need to downgrade to 3A21 (09/09/2002), or try a newer "
609 "BIOS than 3A71 (01/20/2003)\n");
611 "cpufreq scaling has been disabled as a result of this.\n");
622 .callback = acer_cpufreq_pst,
623 .ident =
"Acer Aspire",
637 if (policy->
cpu != 0)
644 fsb = (10 *
cpu_khz) / fid_codes[fidvidstatus.bits.CFID];
649 pr_debug(
"FSB: %3dMHz\n", fsb/1000);
653 "Trying ACPI instead\n");
654 result = powernow_acpi_init();
656 result = powernow_decode_bios(fidvidstatus.bits.MFID,
657 fidvidstatus.bits.SVID);
663 result = powernow_acpi_init();
666 "ACPI and legacy methods failed\n");
670 latency = fixup_sgtc();
679 minimum_speed/1000, maximum_speed/1000);
681 policy->
cpuinfo.transition_latency =
682 cpufreq_scale(2000000
UL, fsb, latency);
684 policy->
cur = powernow_get(0);
695 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
696 if (acpi_processor_perf) {
699 kfree(acpi_processor_perf);
703 kfree(powernow_table);
707 static struct freq_attr *powernow_table_attr[] = {
713 .verify = powernow_verify,
714 .target = powernow_target,
716 #ifdef CONFIG_X86_POWERNOW_K7_ACPI
719 .init = powernow_cpu_init,
720 .exit = powernow_cpu_exit,
721 .name =
"powernow-k7",
723 .attr = powernow_table_attr,
726 static int __init powernow_init(
void)
728 if (check_powernow() == 0)
734 static void __exit powernow_exit(
void)