aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/powernow-k8.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/cpufreq/powernow-k8.c')
-rw-r--r--drivers/cpufreq/powernow-k8.c406
1 files changed, 40 insertions, 366 deletions
diff --git a/drivers/cpufreq/powernow-k8.c b/drivers/cpufreq/powernow-k8.c
index 1a40935c85fd..129e80bfff22 100644
--- a/drivers/cpufreq/powernow-k8.c
+++ b/drivers/cpufreq/powernow-k8.c
@@ -48,22 +48,12 @@
48#define PFX "powernow-k8: " 48#define PFX "powernow-k8: "
49#define VERSION "version 2.20.00" 49#define VERSION "version 2.20.00"
50#include "powernow-k8.h" 50#include "powernow-k8.h"
51#include "mperf.h"
52 51
53/* serialize freq changes */ 52/* serialize freq changes */
54static DEFINE_MUTEX(fidvid_mutex); 53static DEFINE_MUTEX(fidvid_mutex);
55 54
56static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data); 55static DEFINE_PER_CPU(struct powernow_k8_data *, powernow_data);
57 56
58static int cpu_family = CPU_OPTERON;
59
60/* array to map SW pstate number to acpi state */
61static u32 ps_to_as[8];
62
63/* core performance boost */
64static bool cpb_capable, cpb_enabled;
65static struct msr __percpu *msrs;
66
67static struct cpufreq_driver cpufreq_amd64_driver; 57static struct cpufreq_driver cpufreq_amd64_driver;
68 58
69#ifndef CONFIG_SMP 59#ifndef CONFIG_SMP
@@ -85,12 +75,6 @@ static u32 find_khz_freq_from_fid(u32 fid)
85 return 1000 * find_freq_from_fid(fid); 75 return 1000 * find_freq_from_fid(fid);
86} 76}
87 77
88static u32 find_khz_freq_from_pstate(struct cpufreq_frequency_table *data,
89 u32 pstate)
90{
91 return data[ps_to_as[pstate]].frequency;
92}
93
94/* Return the vco fid for an input fid 78/* Return the vco fid for an input fid
95 * 79 *
96 * Each "low" fid has corresponding "high" fid, and you can get to "low" fids 80 * Each "low" fid has corresponding "high" fid, and you can get to "low" fids
@@ -113,9 +97,6 @@ static int pending_bit_stuck(void)
113{ 97{
114 u32 lo, hi; 98 u32 lo, hi;
115 99
116 if (cpu_family == CPU_HW_PSTATE)
117 return 0;
118
119 rdmsr(MSR_FIDVID_STATUS, lo, hi); 100 rdmsr(MSR_FIDVID_STATUS, lo, hi);
120 return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0; 101 return lo & MSR_S_LO_CHANGE_PENDING ? 1 : 0;
121} 102}
@@ -129,20 +110,6 @@ static int query_current_values_with_pending_wait(struct powernow_k8_data *data)
129 u32 lo, hi; 110 u32 lo, hi;
130 u32 i = 0; 111 u32 i = 0;
131 112
132 if (cpu_family == CPU_HW_PSTATE) {
133 rdmsr(MSR_PSTATE_STATUS, lo, hi);
134 i = lo & HW_PSTATE_MASK;
135 data->currpstate = i;
136
137 /*
138 * a workaround for family 11h erratum 311 might cause
139 * an "out-of-range Pstate if the core is in Pstate-0
140 */
141 if ((boot_cpu_data.x86 == 0x11) && (i >= data->numps))
142 data->currpstate = HW_PSTATE_0;
143
144 return 0;
145 }
146 do { 113 do {
147 if (i++ > 10000) { 114 if (i++ > 10000) {
148 pr_debug("detected change pending stuck\n"); 115 pr_debug("detected change pending stuck\n");
@@ -299,14 +266,6 @@ static int decrease_vid_code_by_step(struct powernow_k8_data *data,
299 return 0; 266 return 0;
300} 267}
301 268
302/* Change hardware pstate by single MSR write */
303static int transition_pstate(struct powernow_k8_data *data, u32 pstate)
304{
305 wrmsr(MSR_PSTATE_CTRL, pstate, 0);
306 data->currpstate = pstate;
307 return 0;
308}
309
310/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */ 269/* Change Opteron/Athlon64 fid and vid, by the 3 phases. */
311static int transition_fid_vid(struct powernow_k8_data *data, 270static int transition_fid_vid(struct powernow_k8_data *data,
312 u32 reqfid, u32 reqvid) 271 u32 reqfid, u32 reqvid)
@@ -523,8 +482,6 @@ static int core_voltage_post_transition(struct powernow_k8_data *data,
523static const struct x86_cpu_id powernow_k8_ids[] = { 482static const struct x86_cpu_id powernow_k8_ids[] = {
524 /* IO based frequency switching */ 483 /* IO based frequency switching */
525 { X86_VENDOR_AMD, 0xf }, 484 { X86_VENDOR_AMD, 0xf },
526 /* MSR based frequency switching supported */
527 X86_FEATURE_MATCH(X86_FEATURE_HW_PSTATE),
528 {} 485 {}
529}; 486};
530MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids); 487MODULE_DEVICE_TABLE(x86cpu, powernow_k8_ids);
@@ -560,15 +517,8 @@ static void check_supported_cpu(void *_rc)
560 "Power state transitions not supported\n"); 517 "Power state transitions not supported\n");
561 return; 518 return;
562 } 519 }
563 } else { /* must be a HW Pstate capable processor */ 520 *rc = 0;
564 cpuid(CPUID_FREQ_VOLT_CAPABILITIES, &eax, &ebx, &ecx, &edx);
565 if ((edx & USE_HW_PSTATE) == USE_HW_PSTATE)
566 cpu_family = CPU_HW_PSTATE;
567 else
568 return;
569 } 521 }
570
571 *rc = 0;
572} 522}
573 523
574static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst, 524static int check_pst_table(struct powernow_k8_data *data, struct pst_s *pst,
@@ -632,18 +582,11 @@ static void print_basics(struct powernow_k8_data *data)
632 for (j = 0; j < data->numps; j++) { 582 for (j = 0; j < data->numps; j++) {
633 if (data->powernow_table[j].frequency != 583 if (data->powernow_table[j].frequency !=
634 CPUFREQ_ENTRY_INVALID) { 584 CPUFREQ_ENTRY_INVALID) {
635 if (cpu_family == CPU_HW_PSTATE) {
636 printk(KERN_INFO PFX
637 " %d : pstate %d (%d MHz)\n", j,
638 data->powernow_table[j].index,
639 data->powernow_table[j].frequency/1000);
640 } else {
641 printk(KERN_INFO PFX 585 printk(KERN_INFO PFX
642 "fid 0x%x (%d MHz), vid 0x%x\n", 586 "fid 0x%x (%d MHz), vid 0x%x\n",
643 data->powernow_table[j].index & 0xff, 587 data->powernow_table[j].index & 0xff,
644 data->powernow_table[j].frequency/1000, 588 data->powernow_table[j].frequency/1000,
645 data->powernow_table[j].index >> 8); 589 data->powernow_table[j].index >> 8);
646 }
647 } 590 }
648 } 591 }
649 if (data->batps) 592 if (data->batps)
@@ -651,20 +594,6 @@ static void print_basics(struct powernow_k8_data *data)
651 data->batps); 594 data->batps);
652} 595}
653 596
654static u32 freq_from_fid_did(u32 fid, u32 did)
655{
656 u32 mhz = 0;
657
658 if (boot_cpu_data.x86 == 0x10)
659 mhz = (100 * (fid + 0x10)) >> did;
660 else if (boot_cpu_data.x86 == 0x11)
661 mhz = (100 * (fid + 8)) >> did;
662 else
663 BUG();
664
665 return mhz * 1000;
666}
667
668static int fill_powernow_table(struct powernow_k8_data *data, 597static int fill_powernow_table(struct powernow_k8_data *data,
669 struct pst_s *pst, u8 maxvid) 598 struct pst_s *pst, u8 maxvid)
670{ 599{
@@ -824,7 +753,7 @@ static void powernow_k8_acpi_pst_values(struct powernow_k8_data *data,
824{ 753{
825 u64 control; 754 u64 control;
826 755
827 if (!data->acpi_data.state_count || (cpu_family == CPU_HW_PSTATE)) 756 if (!data->acpi_data.state_count)
828 return; 757 return;
829 758
830 control = data->acpi_data.states[index].control; 759 control = data->acpi_data.states[index].control;
@@ -875,10 +804,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
875 data->numps = data->acpi_data.state_count; 804 data->numps = data->acpi_data.state_count;
876 powernow_k8_acpi_pst_values(data, 0); 805 powernow_k8_acpi_pst_values(data, 0);
877 806
878 if (cpu_family == CPU_HW_PSTATE) 807 ret_val = fill_powernow_table_fidvid(data, powernow_table);
879 ret_val = fill_powernow_table_pstate(data, powernow_table);
880 else
881 ret_val = fill_powernow_table_fidvid(data, powernow_table);
882 if (ret_val) 808 if (ret_val)
883 goto err_out_mem; 809 goto err_out_mem;
884 810
@@ -915,51 +841,6 @@ err_out:
915 return ret_val; 841 return ret_val;
916} 842}
917 843
918static int fill_powernow_table_pstate(struct powernow_k8_data *data,
919 struct cpufreq_frequency_table *powernow_table)
920{
921 int i;
922 u32 hi = 0, lo = 0;
923 rdmsr(MSR_PSTATE_CUR_LIMIT, lo, hi);
924 data->max_hw_pstate = (lo & HW_PSTATE_MAX_MASK) >> HW_PSTATE_MAX_SHIFT;
925
926 for (i = 0; i < data->acpi_data.state_count; i++) {
927 u32 index;
928
929 index = data->acpi_data.states[i].control & HW_PSTATE_MASK;
930 if (index > data->max_hw_pstate) {
931 printk(KERN_ERR PFX "invalid pstate %d - "
932 "bad value %d.\n", i, index);
933 printk(KERN_ERR PFX "Please report to BIOS "
934 "manufacturer\n");
935 invalidate_entry(powernow_table, i);
936 continue;
937 }
938
939 ps_to_as[index] = i;
940
941 /* Frequency may be rounded for these */
942 if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
943 || boot_cpu_data.x86 == 0x11) {
944
945 rdmsr(MSR_PSTATE_DEF_BASE + index, lo, hi);
946 if (!(hi & HW_PSTATE_VALID_MASK)) {
947 pr_debug("invalid pstate %d, ignoring\n", index);
948 invalidate_entry(powernow_table, i);
949 continue;
950 }
951
952 powernow_table[i].frequency =
953 freq_from_fid_did(lo & 0x3f, (lo >> 6) & 7);
954 } else
955 powernow_table[i].frequency =
956 data->acpi_data.states[i].core_frequency * 1000;
957
958 powernow_table[i].index = index;
959 }
960 return 0;
961}
962
963static int fill_powernow_table_fidvid(struct powernow_k8_data *data, 844static int fill_powernow_table_fidvid(struct powernow_k8_data *data,
964 struct cpufreq_frequency_table *powernow_table) 845 struct cpufreq_frequency_table *powernow_table)
965{ 846{
@@ -1036,15 +917,7 @@ static int get_transition_latency(struct powernow_k8_data *data)
1036 max_latency = cur_latency; 917 max_latency = cur_latency;
1037 } 918 }
1038 if (max_latency == 0) { 919 if (max_latency == 0) {
1039 /* 920 pr_err(FW_WARN PFX "Invalid zero transition latency\n");
1040 * Fam 11h and later may return 0 as transition latency. This
1041 * is intended and means "very fast". While cpufreq core and
1042 * governors currently can handle that gracefully, better set it
1043 * to 1 to avoid problems in the future.
1044 */
1045 if (boot_cpu_data.x86 < 0x11)
1046 printk(KERN_ERR FW_WARN PFX "Invalid zero transition "
1047 "latency\n");
1048 max_latency = 1; 921 max_latency = 1;
1049 } 922 }
1050 /* value in usecs, needs to be in nanoseconds */ 923 /* value in usecs, needs to be in nanoseconds */
@@ -1104,40 +977,6 @@ static int transition_frequency_fidvid(struct powernow_k8_data *data,
1104 return res; 977 return res;
1105} 978}
1106 979
1107/* Take a frequency, and issue the hardware pstate transition command */
1108static int transition_frequency_pstate(struct powernow_k8_data *data,
1109 unsigned int index)
1110{
1111 u32 pstate = 0;
1112 int res, i;
1113 struct cpufreq_freqs freqs;
1114
1115 pr_debug("cpu %d transition to index %u\n", smp_processor_id(), index);
1116
1117 /* get MSR index for hardware pstate transition */
1118 pstate = index & HW_PSTATE_MASK;
1119 if (pstate > data->max_hw_pstate)
1120 return -EINVAL;
1121
1122 freqs.old = find_khz_freq_from_pstate(data->powernow_table,
1123 data->currpstate);
1124 freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
1125
1126 for_each_cpu(i, data->available_cores) {
1127 freqs.cpu = i;
1128 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
1129 }
1130
1131 res = transition_pstate(data, pstate);
1132 freqs.new = find_khz_freq_from_pstate(data->powernow_table, pstate);
1133
1134 for_each_cpu(i, data->available_cores) {
1135 freqs.cpu = i;
1136 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
1137 }
1138 return res;
1139}
1140
1141struct powernowk8_target_arg { 980struct powernowk8_target_arg {
1142 struct cpufreq_policy *pol; 981 struct cpufreq_policy *pol;
1143 unsigned targfreq; 982 unsigned targfreq;
@@ -1173,18 +1012,15 @@ static long powernowk8_target_fn(void *arg)
1173 if (query_current_values_with_pending_wait(data)) 1012 if (query_current_values_with_pending_wait(data))
1174 return -EIO; 1013 return -EIO;
1175 1014
1176 if (cpu_family != CPU_HW_PSTATE) { 1015 pr_debug("targ: curr fid 0x%x, vid 0x%x\n",
1177 pr_debug("targ: curr fid 0x%x, vid 0x%x\n", 1016 data->currfid, data->currvid);
1178 data->currfid, data->currvid);
1179 1017
1180 if ((checkvid != data->currvid) || 1018 if ((checkvid != data->currvid) ||
1181 (checkfid != data->currfid)) { 1019 (checkfid != data->currfid)) {
1182 printk(KERN_INFO PFX 1020 pr_info(PFX
1183 "error - out of sync, fix 0x%x 0x%x, " 1021 "error - out of sync, fix 0x%x 0x%x, vid 0x%x 0x%x\n",
1184 "vid 0x%x 0x%x\n", 1022 checkfid, data->currfid,
1185 checkfid, data->currfid, 1023 checkvid, data->currvid);
1186 checkvid, data->currvid);
1187 }
1188 } 1024 }
1189 1025
1190 if (cpufreq_frequency_table_target(pol, data->powernow_table, 1026 if (cpufreq_frequency_table_target(pol, data->powernow_table,
@@ -1195,11 +1031,8 @@ static long powernowk8_target_fn(void *arg)
1195 1031
1196 powernow_k8_acpi_pst_values(data, newstate); 1032 powernow_k8_acpi_pst_values(data, newstate);
1197 1033
1198 if (cpu_family == CPU_HW_PSTATE) 1034 ret = transition_frequency_fidvid(data, newstate);
1199 ret = transition_frequency_pstate(data, 1035
1200 data->powernow_table[newstate].index);
1201 else
1202 ret = transition_frequency_fidvid(data, newstate);
1203 if (ret) { 1036 if (ret) {
1204 printk(KERN_ERR PFX "transition frequency failed\n"); 1037 printk(KERN_ERR PFX "transition frequency failed\n");
1205 mutex_unlock(&fidvid_mutex); 1038 mutex_unlock(&fidvid_mutex);
@@ -1207,11 +1040,7 @@ static long powernowk8_target_fn(void *arg)
1207 } 1040 }
1208 mutex_unlock(&fidvid_mutex); 1041 mutex_unlock(&fidvid_mutex);
1209 1042
1210 if (cpu_family == CPU_HW_PSTATE) 1043 pol->cur = find_khz_freq_from_fid(data->currfid);
1211 pol->cur = find_khz_freq_from_pstate(data->powernow_table,
1212 data->powernow_table[newstate].index);
1213 else
1214 pol->cur = find_khz_freq_from_fid(data->currfid);
1215 1044
1216 return 0; 1045 return 0;
1217} 1046}
@@ -1264,22 +1093,23 @@ static void __cpuinit powernowk8_cpu_init_on_cpu(void *_init_on_cpu)
1264 return; 1093 return;
1265 } 1094 }
1266 1095
1267 if (cpu_family == CPU_OPTERON) 1096 fidvid_msr_init();
1268 fidvid_msr_init();
1269 1097
1270 init_on_cpu->rc = 0; 1098 init_on_cpu->rc = 0;
1271} 1099}
1272 1100
1101static const char missing_pss_msg[] =
1102 KERN_ERR
1103 FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
1104 FW_BUG PFX "First, make sure Cool'N'Quiet is enabled in the BIOS.\n"
1105 FW_BUG PFX "If that doesn't help, try upgrading your BIOS.\n";
1106
1273/* per CPU init entry point to the driver */ 1107/* per CPU init entry point to the driver */
1274static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol) 1108static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1275{ 1109{
1276 static const char ACPI_PSS_BIOS_BUG_MSG[] =
1277 KERN_ERR FW_BUG PFX "No compatible ACPI _PSS objects found.\n"
1278 FW_BUG PFX "Try again with latest BIOS.\n";
1279 struct powernow_k8_data *data; 1110 struct powernow_k8_data *data;
1280 struct init_on_cpu init_on_cpu; 1111 struct init_on_cpu init_on_cpu;
1281 int rc; 1112 int rc;
1282 struct cpuinfo_x86 *c = &cpu_data(pol->cpu);
1283 1113
1284 if (!cpu_online(pol->cpu)) 1114 if (!cpu_online(pol->cpu))
1285 return -ENODEV; 1115 return -ENODEV;
@@ -1295,7 +1125,6 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1295 } 1125 }
1296 1126
1297 data->cpu = pol->cpu; 1127 data->cpu = pol->cpu;
1298 data->currpstate = HW_PSTATE_INVALID;
1299 1128
1300 if (powernow_k8_cpu_init_acpi(data)) { 1129 if (powernow_k8_cpu_init_acpi(data)) {
1301 /* 1130 /*
@@ -1303,7 +1132,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1303 * an UP version, and is deprecated by AMD. 1132 * an UP version, and is deprecated by AMD.
1304 */ 1133 */
1305 if (num_online_cpus() != 1) { 1134 if (num_online_cpus() != 1) {
1306 printk_once(ACPI_PSS_BIOS_BUG_MSG); 1135 printk_once(missing_pss_msg);
1307 goto err_out; 1136 goto err_out;
1308 } 1137 }
1309 if (pol->cpu != 0) { 1138 if (pol->cpu != 0) {
@@ -1332,17 +1161,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1332 if (rc != 0) 1161 if (rc != 0)
1333 goto err_out_exit_acpi; 1162 goto err_out_exit_acpi;
1334 1163
1335 if (cpu_family == CPU_HW_PSTATE) 1164 cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
1336 cpumask_copy(pol->cpus, cpumask_of(pol->cpu));
1337 else
1338 cpumask_copy(pol->cpus, cpu_core_mask(pol->cpu));
1339 data->available_cores = pol->cpus; 1165 data->available_cores = pol->cpus;
1340 1166
1341 if (cpu_family == CPU_HW_PSTATE) 1167 pol->cur = find_khz_freq_from_fid(data->currfid);
1342 pol->cur = find_khz_freq_from_pstate(data->powernow_table,
1343 data->currpstate);
1344 else
1345 pol->cur = find_khz_freq_from_fid(data->currfid);
1346 pr_debug("policy current frequency %d kHz\n", pol->cur); 1168 pr_debug("policy current frequency %d kHz\n", pol->cur);
1347 1169
1348 /* min/max the cpu is capable of */ 1170 /* min/max the cpu is capable of */
@@ -1354,18 +1176,10 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1354 return -EINVAL; 1176 return -EINVAL;
1355 } 1177 }
1356 1178
1357 /* Check for APERF/MPERF support in hardware */
1358 if (cpu_has(c, X86_FEATURE_APERFMPERF))
1359 cpufreq_amd64_driver.getavg = cpufreq_get_measured_perf;
1360
1361 cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu); 1179 cpufreq_frequency_table_get_attr(data->powernow_table, pol->cpu);
1362 1180
1363 if (cpu_family == CPU_HW_PSTATE) 1181 pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
1364 pr_debug("cpu_init done, current pstate 0x%x\n", 1182 data->currfid, data->currvid);
1365 data->currpstate);
1366 else
1367 pr_debug("cpu_init done, current fid 0x%x, vid 0x%x\n",
1368 data->currfid, data->currvid);
1369 1183
1370 per_cpu(powernow_data, pol->cpu) = data; 1184 per_cpu(powernow_data, pol->cpu) = data;
1371 1185
@@ -1418,88 +1232,15 @@ static unsigned int powernowk8_get(unsigned int cpu)
1418 if (err) 1232 if (err)
1419 goto out; 1233 goto out;
1420 1234
1421 if (cpu_family == CPU_HW_PSTATE) 1235 khz = find_khz_freq_from_fid(data->currfid);
1422 khz = find_khz_freq_from_pstate(data->powernow_table,
1423 data->currpstate);
1424 else
1425 khz = find_khz_freq_from_fid(data->currfid);
1426 1236
1427 1237
1428out: 1238out:
1429 return khz; 1239 return khz;
1430} 1240}
1431 1241
1432static void _cpb_toggle_msrs(bool t)
1433{
1434 int cpu;
1435
1436 get_online_cpus();
1437
1438 rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
1439
1440 for_each_cpu(cpu, cpu_online_mask) {
1441 struct msr *reg = per_cpu_ptr(msrs, cpu);
1442 if (t)
1443 reg->l &= ~BIT(25);
1444 else
1445 reg->l |= BIT(25);
1446 }
1447 wrmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
1448
1449 put_online_cpus();
1450}
1451
1452/*
1453 * Switch on/off core performance boosting.
1454 *
1455 * 0=disable
1456 * 1=enable.
1457 */
1458static void cpb_toggle(bool t)
1459{
1460 if (!cpb_capable)
1461 return;
1462
1463 if (t && !cpb_enabled) {
1464 cpb_enabled = true;
1465 _cpb_toggle_msrs(t);
1466 printk(KERN_INFO PFX "Core Boosting enabled.\n");
1467 } else if (!t && cpb_enabled) {
1468 cpb_enabled = false;
1469 _cpb_toggle_msrs(t);
1470 printk(KERN_INFO PFX "Core Boosting disabled.\n");
1471 }
1472}
1473
1474static ssize_t store_cpb(struct cpufreq_policy *policy, const char *buf,
1475 size_t count)
1476{
1477 int ret = -EINVAL;
1478 unsigned long val = 0;
1479
1480 ret = strict_strtoul(buf, 10, &val);
1481 if (!ret && (val == 0 || val == 1) && cpb_capable)
1482 cpb_toggle(val);
1483 else
1484 return -EINVAL;
1485
1486 return count;
1487}
1488
1489static ssize_t show_cpb(struct cpufreq_policy *policy, char *buf)
1490{
1491 return sprintf(buf, "%u\n", cpb_enabled);
1492}
1493
1494#define define_one_rw(_name) \
1495static struct freq_attr _name = \
1496__ATTR(_name, 0644, show_##_name, store_##_name)
1497
1498define_one_rw(cpb);
1499
1500static struct freq_attr *powernow_k8_attr[] = { 1242static struct freq_attr *powernow_k8_attr[] = {
1501 &cpufreq_freq_attr_scaling_available_freqs, 1243 &cpufreq_freq_attr_scaling_available_freqs,
1502 &cpb,
1503 NULL, 1244 NULL,
1504}; 1245};
1505 1246
@@ -1515,53 +1256,18 @@ static struct cpufreq_driver cpufreq_amd64_driver = {
1515 .attr = powernow_k8_attr, 1256 .attr = powernow_k8_attr,
1516}; 1257};
1517 1258
1518/*
1519 * Clear the boost-disable flag on the CPU_DOWN path so that this cpu
1520 * cannot block the remaining ones from boosting. On the CPU_UP path we
1521 * simply keep the boost-disable flag in sync with the current global
1522 * state.
1523 */
1524static int cpb_notify(struct notifier_block *nb, unsigned long action,
1525 void *hcpu)
1526{
1527 unsigned cpu = (long)hcpu;
1528 u32 lo, hi;
1529
1530 switch (action) {
1531 case CPU_UP_PREPARE:
1532 case CPU_UP_PREPARE_FROZEN:
1533
1534 if (!cpb_enabled) {
1535 rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
1536 lo |= BIT(25);
1537 wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
1538 }
1539 break;
1540
1541 case CPU_DOWN_PREPARE:
1542 case CPU_DOWN_PREPARE_FROZEN:
1543 rdmsr_on_cpu(cpu, MSR_K7_HWCR, &lo, &hi);
1544 lo &= ~BIT(25);
1545 wrmsr_on_cpu(cpu, MSR_K7_HWCR, lo, hi);
1546 break;
1547
1548 default:
1549 break;
1550 }
1551
1552 return NOTIFY_OK;
1553}
1554
1555static struct notifier_block cpb_nb = {
1556 .notifier_call = cpb_notify,
1557};
1558
1559/* driver entry point for init */ 1259/* driver entry point for init */
1560static int __cpuinit powernowk8_init(void) 1260static int __cpuinit powernowk8_init(void)
1561{ 1261{
1562 unsigned int i, supported_cpus = 0, cpu; 1262 unsigned int i, supported_cpus = 0;
1563 int rv; 1263 int rv;
1564 1264
1265 if (static_cpu_has(X86_FEATURE_HW_PSTATE)) {
1266 pr_warn(PFX "this CPU is not supported anymore, using acpi-cpufreq instead.\n");
1267 request_module("acpi-cpufreq");
1268 return -ENODEV;
1269 }
1270
1565 if (!x86_match_cpu(powernow_k8_ids)) 1271 if (!x86_match_cpu(powernow_k8_ids))
1566 return -ENODEV; 1272 return -ENODEV;
1567 1273
@@ -1575,38 +1281,13 @@ static int __cpuinit powernowk8_init(void)
1575 if (supported_cpus != num_online_cpus()) 1281 if (supported_cpus != num_online_cpus())
1576 return -ENODEV; 1282 return -ENODEV;
1577 1283
1578 printk(KERN_INFO PFX "Found %d %s (%d cpu cores) (" VERSION ")\n", 1284 rv = cpufreq_register_driver(&cpufreq_amd64_driver);
1579 num_online_nodes(), boot_cpu_data.x86_model_id, supported_cpus);
1580
1581 if (boot_cpu_has(X86_FEATURE_CPB)) {
1582
1583 cpb_capable = true;
1584
1585 msrs = msrs_alloc();
1586 if (!msrs) {
1587 printk(KERN_ERR "%s: Error allocating msrs!\n", __func__);
1588 return -ENOMEM;
1589 }
1590
1591 register_cpu_notifier(&cpb_nb);
1592
1593 rdmsr_on_cpus(cpu_online_mask, MSR_K7_HWCR, msrs);
1594 1285
1595 for_each_cpu(cpu, cpu_online_mask) { 1286 if (!rv)
1596 struct msr *reg = per_cpu_ptr(msrs, cpu); 1287 pr_info(PFX "Found %d %s (%d cpu cores) (" VERSION ")\n",
1597 cpb_enabled |= !(!!(reg->l & BIT(25))); 1288 num_online_nodes(), boot_cpu_data.x86_model_id,
1598 } 1289 supported_cpus);
1599 1290
1600 printk(KERN_INFO PFX "Core Performance Boosting: %s.\n",
1601 (cpb_enabled ? "on" : "off"));
1602 }
1603
1604 rv = cpufreq_register_driver(&cpufreq_amd64_driver);
1605 if (rv < 0 && boot_cpu_has(X86_FEATURE_CPB)) {
1606 unregister_cpu_notifier(&cpb_nb);
1607 msrs_free(msrs);
1608 msrs = NULL;
1609 }
1610 return rv; 1291 return rv;
1611} 1292}
1612 1293
@@ -1615,13 +1296,6 @@ static void __exit powernowk8_exit(void)
1615{ 1296{
1616 pr_debug("exit\n"); 1297 pr_debug("exit\n");
1617 1298
1618 if (boot_cpu_has(X86_FEATURE_CPB)) {
1619 msrs_free(msrs);
1620 msrs = NULL;
1621
1622 unregister_cpu_notifier(&cpb_nb);
1623 }
1624
1625 cpufreq_unregister_driver(&cpufreq_amd64_driver); 1299 cpufreq_unregister_driver(&cpufreq_amd64_driver);
1626} 1300}
1627 1301