0001
0002
0003
0004
0005
0006
0007
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009
0010 #include <linux/kernel.h>
0011 #include <linux/module.h>
0012 #include <linux/init.h>
0013 #include <linux/cpufreq.h>
0014 #include <linux/ioport.h>
0015 #include <linux/slab.h>
0016 #include <linux/timex.h>
0017 #include <linux/io.h>
0018 #include <linux/delay.h>
0019
0020 #include <asm/cpu_device_id.h>
0021 #include <asm/msr.h>
0022 #include <asm/tsc.h>
0023
0024 #if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
0025 #include <linux/acpi.h>
0026 #include <acpi/processor.h>
0027 #endif
0028
0029 #define EPS_BRAND_C7M 0
0030 #define EPS_BRAND_C7 1
0031 #define EPS_BRAND_EDEN 2
0032 #define EPS_BRAND_C3 3
0033 #define EPS_BRAND_C7D 4
0034
0035 struct eps_cpu_data {
0036 u32 fsb;
0037 #if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
0038 u32 bios_limit;
0039 #endif
0040 struct cpufreq_frequency_table freq_table[];
0041 };
0042
0043 static struct eps_cpu_data *eps_cpu[NR_CPUS];
0044
0045
0046 static int freq_failsafe_off;
0047 static int voltage_failsafe_off;
0048 static int set_max_voltage;
0049
0050 #if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
0051 static int ignore_acpi_limit;
0052
0053 static struct acpi_processor_performance *eps_acpi_cpu_perf;
0054
0055
0056 static int eps_acpi_init(void)
0057 {
0058 eps_acpi_cpu_perf = kzalloc(sizeof(*eps_acpi_cpu_perf),
0059 GFP_KERNEL);
0060 if (!eps_acpi_cpu_perf)
0061 return -ENOMEM;
0062
0063 if (!zalloc_cpumask_var(&eps_acpi_cpu_perf->shared_cpu_map,
0064 GFP_KERNEL)) {
0065 kfree(eps_acpi_cpu_perf);
0066 eps_acpi_cpu_perf = NULL;
0067 return -ENOMEM;
0068 }
0069
0070 if (acpi_processor_register_performance(eps_acpi_cpu_perf, 0)) {
0071 free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map);
0072 kfree(eps_acpi_cpu_perf);
0073 eps_acpi_cpu_perf = NULL;
0074 return -EIO;
0075 }
0076 return 0;
0077 }
0078
0079 static int eps_acpi_exit(struct cpufreq_policy *policy)
0080 {
0081 if (eps_acpi_cpu_perf) {
0082 acpi_processor_unregister_performance(0);
0083 free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map);
0084 kfree(eps_acpi_cpu_perf);
0085 eps_acpi_cpu_perf = NULL;
0086 }
0087 return 0;
0088 }
0089 #endif
0090
0091 static unsigned int eps_get(unsigned int cpu)
0092 {
0093 struct eps_cpu_data *centaur;
0094 u32 lo, hi;
0095
0096 if (cpu)
0097 return 0;
0098 centaur = eps_cpu[cpu];
0099 if (centaur == NULL)
0100 return 0;
0101
0102
0103 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
0104 return centaur->fsb * ((lo >> 8) & 0xff);
0105 }
0106
0107 static int eps_set_state(struct eps_cpu_data *centaur,
0108 struct cpufreq_policy *policy,
0109 u32 dest_state)
0110 {
0111 u32 lo, hi;
0112 int i;
0113
0114
0115 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
0116 i = 0;
0117 while (lo & ((1 << 16) | (1 << 17))) {
0118 udelay(16);
0119 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
0120 i++;
0121 if (unlikely(i > 64)) {
0122 return -ENODEV;
0123 }
0124 }
0125
0126 wrmsr(MSR_IA32_PERF_CTL, dest_state & 0xffff, 0);
0127
0128 i = 0;
0129 do {
0130 udelay(16);
0131 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
0132 i++;
0133 if (unlikely(i > 64)) {
0134 return -ENODEV;
0135 }
0136 } while (lo & ((1 << 16) | (1 << 17)));
0137
0138 #ifdef DEBUG
0139 {
0140 u8 current_multiplier, current_voltage;
0141
0142
0143 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
0144 current_voltage = lo & 0xff;
0145 pr_info("Current voltage = %dmV\n", current_voltage * 16 + 700);
0146 current_multiplier = (lo >> 8) & 0xff;
0147 pr_info("Current multiplier = %d\n", current_multiplier);
0148 }
0149 #endif
0150 return 0;
0151 }
0152
0153 static int eps_target(struct cpufreq_policy *policy, unsigned int index)
0154 {
0155 struct eps_cpu_data *centaur;
0156 unsigned int cpu = policy->cpu;
0157 unsigned int dest_state;
0158 int ret;
0159
0160 if (unlikely(eps_cpu[cpu] == NULL))
0161 return -ENODEV;
0162 centaur = eps_cpu[cpu];
0163
0164
0165 dest_state = centaur->freq_table[index].driver_data & 0xffff;
0166 ret = eps_set_state(centaur, policy, dest_state);
0167 if (ret)
0168 pr_err("Timeout!\n");
0169 return ret;
0170 }
0171
0172 static int eps_cpu_init(struct cpufreq_policy *policy)
0173 {
0174 unsigned int i;
0175 u32 lo, hi;
0176 u64 val;
0177 u8 current_multiplier, current_voltage;
0178 u8 max_multiplier, max_voltage;
0179 u8 min_multiplier, min_voltage;
0180 u8 brand = 0;
0181 u32 fsb;
0182 struct eps_cpu_data *centaur;
0183 struct cpuinfo_x86 *c = &cpu_data(0);
0184 struct cpufreq_frequency_table *f_table;
0185 int k, step, voltage;
0186 int states;
0187 #if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
0188 unsigned int limit;
0189 #endif
0190
0191 if (policy->cpu != 0)
0192 return -ENODEV;
0193
0194
0195 pr_info("Detected VIA ");
0196
0197 switch (c->x86_model) {
0198 case 10:
0199 rdmsr(0x1153, lo, hi);
0200 brand = (((lo >> 2) ^ lo) >> 18) & 3;
0201 pr_cont("Model A ");
0202 break;
0203 case 13:
0204 rdmsr(0x1154, lo, hi);
0205 brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff;
0206 pr_cont("Model D ");
0207 break;
0208 }
0209
0210 switch (brand) {
0211 case EPS_BRAND_C7M:
0212 pr_cont("C7-M\n");
0213 break;
0214 case EPS_BRAND_C7:
0215 pr_cont("C7\n");
0216 break;
0217 case EPS_BRAND_EDEN:
0218 pr_cont("Eden\n");
0219 break;
0220 case EPS_BRAND_C7D:
0221 pr_cont("C7-D\n");
0222 break;
0223 case EPS_BRAND_C3:
0224 pr_cont("C3\n");
0225 return -ENODEV;
0226 }
0227
0228 rdmsrl(MSR_IA32_MISC_ENABLE, val);
0229 if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
0230 val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
0231 wrmsrl(MSR_IA32_MISC_ENABLE, val);
0232
0233 rdmsrl(MSR_IA32_MISC_ENABLE, val);
0234 if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
0235 pr_info("Can't enable Enhanced PowerSaver\n");
0236 return -ENODEV;
0237 }
0238 }
0239
0240
0241 rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
0242 current_voltage = lo & 0xff;
0243 pr_info("Current voltage = %dmV\n", current_voltage * 16 + 700);
0244 current_multiplier = (lo >> 8) & 0xff;
0245 pr_info("Current multiplier = %d\n", current_multiplier);
0246
0247
0248 max_voltage = hi & 0xff;
0249 pr_info("Highest voltage = %dmV\n", max_voltage * 16 + 700);
0250 max_multiplier = (hi >> 8) & 0xff;
0251 pr_info("Highest multiplier = %d\n", max_multiplier);
0252 min_voltage = (hi >> 16) & 0xff;
0253 pr_info("Lowest voltage = %dmV\n", min_voltage * 16 + 700);
0254 min_multiplier = (hi >> 24) & 0xff;
0255 pr_info("Lowest multiplier = %d\n", min_multiplier);
0256
0257
0258 if (current_multiplier == 0 || max_multiplier == 0
0259 || min_multiplier == 0)
0260 return -EINVAL;
0261 if (current_multiplier > max_multiplier
0262 || max_multiplier <= min_multiplier)
0263 return -EINVAL;
0264 if (current_voltage > 0x1f || max_voltage > 0x1f)
0265 return -EINVAL;
0266 if (max_voltage < min_voltage
0267 || current_voltage < min_voltage
0268 || current_voltage > max_voltage)
0269 return -EINVAL;
0270
0271
0272 if (!freq_failsafe_off && max_multiplier != current_multiplier) {
0273 pr_info("Your processor is running at different frequency then its maximum. Aborting.\n");
0274 pr_info("You can use freq_failsafe_off option to disable this check.\n");
0275 return -EINVAL;
0276 }
0277 if (!voltage_failsafe_off && max_voltage != current_voltage) {
0278 pr_info("Your processor is running at different voltage then its maximum. Aborting.\n");
0279 pr_info("You can use voltage_failsafe_off option to disable this check.\n");
0280 return -EINVAL;
0281 }
0282
0283
0284 fsb = cpu_khz / current_multiplier;
0285
0286 #if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
0287
0288 if (!ignore_acpi_limit && !eps_acpi_init()) {
0289 if (!acpi_processor_get_bios_limit(policy->cpu, &limit)) {
0290 pr_info("ACPI limit %u.%uGHz\n",
0291 limit/1000000,
0292 (limit%1000000)/10000);
0293 eps_acpi_exit(policy);
0294
0295 if (limit && max_multiplier * fsb > limit) {
0296 pr_info("Aborting\n");
0297 return -EINVAL;
0298 }
0299 }
0300 }
0301 #endif
0302
0303
0304
0305 if (brand == EPS_BRAND_C7M && set_max_voltage) {
0306 u32 v;
0307
0308
0309 v = (set_max_voltage - 700) / 16;
0310
0311 if (v >= min_voltage && v <= max_voltage) {
0312 pr_info("Setting %dmV as maximum\n", v * 16 + 700);
0313 max_voltage = v;
0314 }
0315 }
0316
0317
0318 if (brand == EPS_BRAND_C7M)
0319 states = max_multiplier - min_multiplier + 1;
0320 else
0321 states = 2;
0322
0323
0324 centaur = kzalloc(struct_size(centaur, freq_table, states + 1),
0325 GFP_KERNEL);
0326 if (!centaur)
0327 return -ENOMEM;
0328 eps_cpu[0] = centaur;
0329
0330
0331 centaur->fsb = fsb;
0332 #if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
0333 centaur->bios_limit = limit;
0334 #endif
0335
0336
0337 f_table = ¢aur->freq_table[0];
0338 if (brand != EPS_BRAND_C7M) {
0339 f_table[0].frequency = fsb * min_multiplier;
0340 f_table[0].driver_data = (min_multiplier << 8) | min_voltage;
0341 f_table[1].frequency = fsb * max_multiplier;
0342 f_table[1].driver_data = (max_multiplier << 8) | max_voltage;
0343 f_table[2].frequency = CPUFREQ_TABLE_END;
0344 } else {
0345 k = 0;
0346 step = ((max_voltage - min_voltage) * 256)
0347 / (max_multiplier - min_multiplier);
0348 for (i = min_multiplier; i <= max_multiplier; i++) {
0349 voltage = (k * step) / 256 + min_voltage;
0350 f_table[k].frequency = fsb * i;
0351 f_table[k].driver_data = (i << 8) | voltage;
0352 k++;
0353 }
0354 f_table[k].frequency = CPUFREQ_TABLE_END;
0355 }
0356
0357 policy->cpuinfo.transition_latency = 140000;
0358 policy->freq_table = ¢aur->freq_table[0];
0359
0360 return 0;
0361 }
0362
0363 static int eps_cpu_exit(struct cpufreq_policy *policy)
0364 {
0365 unsigned int cpu = policy->cpu;
0366
0367
0368 kfree(eps_cpu[cpu]);
0369 eps_cpu[cpu] = NULL;
0370 return 0;
0371 }
0372
0373 static struct cpufreq_driver eps_driver = {
0374 .verify = cpufreq_generic_frequency_table_verify,
0375 .target_index = eps_target,
0376 .init = eps_cpu_init,
0377 .exit = eps_cpu_exit,
0378 .get = eps_get,
0379 .name = "e_powersaver",
0380 .attr = cpufreq_generic_attr,
0381 };
0382
0383
0384
0385
0386 static const struct x86_cpu_id eps_cpu_id[] = {
0387 X86_MATCH_VENDOR_FAM_FEATURE(CENTAUR, 6, X86_FEATURE_EST, NULL),
0388 {}
0389 };
0390 MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
0391
0392 static int __init eps_init(void)
0393 {
0394 if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
0395 return -ENODEV;
0396 if (cpufreq_register_driver(&eps_driver))
0397 return -EINVAL;
0398 return 0;
0399 }
0400
0401 static void __exit eps_exit(void)
0402 {
0403 cpufreq_unregister_driver(&eps_driver);
0404 }
0405
0406
0407
0408 module_param(freq_failsafe_off, int, 0644);
0409 MODULE_PARM_DESC(freq_failsafe_off, "Disable current vs max frequency check");
0410 module_param(voltage_failsafe_off, int, 0644);
0411 MODULE_PARM_DESC(voltage_failsafe_off, "Disable current vs max voltage check");
0412 #if IS_ENABLED(CONFIG_ACPI_PROCESSOR)
0413 module_param(ignore_acpi_limit, int, 0644);
0414 MODULE_PARM_DESC(ignore_acpi_limit, "Don't check ACPI's processor speed limit");
0415 #endif
0416 module_param(set_max_voltage, int, 0644);
0417 MODULE_PARM_DESC(set_max_voltage, "Set maximum CPU voltage (mV) C7-M only");
0418
0419 MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
0420 MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
0421 MODULE_LICENSE("GPL");
0422
0423 module_init(eps_init);
0424 module_exit(eps_exit);