e_powersaver.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  1. /*
  2. * Based on documentation provided by Dave Jones. Thanks!
  3. *
  4. * Licensed under the terms of the GNU GPL License version 2.
  5. *
  6. * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
  7. */
  8. #include <linux/kernel.h>
  9. #include <linux/module.h>
  10. #include <linux/init.h>
  11. #include <linux/cpufreq.h>
  12. #include <linux/ioport.h>
  13. #include <linux/slab.h>
  14. #include <linux/timex.h>
  15. #include <linux/io.h>
  16. #include <linux/delay.h>
  17. #include <asm/cpu_device_id.h>
  18. #include <asm/msr.h>
  19. #include <asm/tsc.h>
  20. #if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
  21. #include <linux/acpi.h>
  22. #include <acpi/processor.h>
  23. #endif
  24. #define EPS_BRAND_C7M 0
  25. #define EPS_BRAND_C7 1
  26. #define EPS_BRAND_EDEN 2
  27. #define EPS_BRAND_C3 3
  28. #define EPS_BRAND_C7D 4
  29. struct eps_cpu_data {
  30. u32 fsb;
  31. #if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
  32. u32 bios_limit;
  33. #endif
  34. struct cpufreq_frequency_table freq_table[];
  35. };
  36. static struct eps_cpu_data *eps_cpu[NR_CPUS];
  37. /* Module parameters */
  38. static int freq_failsafe_off;
  39. static int voltage_failsafe_off;
  40. static int set_max_voltage;
  41. #if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
  42. static int ignore_acpi_limit;
  43. static struct acpi_processor_performance *eps_acpi_cpu_perf;
  44. /* Minimum necessary to get acpi_processor_get_bios_limit() working */
  45. static int eps_acpi_init(void)
  46. {
  47. eps_acpi_cpu_perf = kzalloc(sizeof(*eps_acpi_cpu_perf),
  48. GFP_KERNEL);
  49. if (!eps_acpi_cpu_perf)
  50. return -ENOMEM;
  51. if (!zalloc_cpumask_var(&eps_acpi_cpu_perf->shared_cpu_map,
  52. GFP_KERNEL)) {
  53. kfree(eps_acpi_cpu_perf);
  54. eps_acpi_cpu_perf = NULL;
  55. return -ENOMEM;
  56. }
  57. if (acpi_processor_register_performance(eps_acpi_cpu_perf, 0)) {
  58. free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map);
  59. kfree(eps_acpi_cpu_perf);
  60. eps_acpi_cpu_perf = NULL;
  61. return -EIO;
  62. }
  63. return 0;
  64. }
  65. static int eps_acpi_exit(struct cpufreq_policy *policy)
  66. {
  67. if (eps_acpi_cpu_perf) {
  68. acpi_processor_unregister_performance(eps_acpi_cpu_perf, 0);
  69. free_cpumask_var(eps_acpi_cpu_perf->shared_cpu_map);
  70. kfree(eps_acpi_cpu_perf);
  71. eps_acpi_cpu_perf = NULL;
  72. }
  73. return 0;
  74. }
  75. #endif
  76. static unsigned int eps_get(unsigned int cpu)
  77. {
  78. struct eps_cpu_data *centaur;
  79. u32 lo, hi;
  80. if (cpu)
  81. return 0;
  82. centaur = eps_cpu[cpu];
  83. if (centaur == NULL)
  84. return 0;
  85. /* Return current frequency */
  86. rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
  87. return centaur->fsb * ((lo >> 8) & 0xff);
  88. }
  89. static int eps_set_state(struct eps_cpu_data *centaur,
  90. struct cpufreq_policy *policy,
  91. u32 dest_state)
  92. {
  93. struct cpufreq_freqs freqs;
  94. u32 lo, hi;
  95. int err = 0;
  96. int i;
  97. freqs.old = eps_get(policy->cpu);
  98. freqs.new = centaur->fsb * ((dest_state >> 8) & 0xff);
  99. cpufreq_notify_transition(policy, &freqs, CPUFREQ_PRECHANGE);
  100. /* Wait while CPU is busy */
  101. rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
  102. i = 0;
  103. while (lo & ((1 << 16) | (1 << 17))) {
  104. udelay(16);
  105. rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
  106. i++;
  107. if (unlikely(i > 64)) {
  108. err = -ENODEV;
  109. goto postchange;
  110. }
  111. }
  112. /* Set new multiplier and voltage */
  113. wrmsr(MSR_IA32_PERF_CTL, dest_state & 0xffff, 0);
  114. /* Wait until transition end */
  115. i = 0;
  116. do {
  117. udelay(16);
  118. rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
  119. i++;
  120. if (unlikely(i > 64)) {
  121. err = -ENODEV;
  122. goto postchange;
  123. }
  124. } while (lo & ((1 << 16) | (1 << 17)));
  125. /* Return current frequency */
  126. postchange:
  127. rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
  128. freqs.new = centaur->fsb * ((lo >> 8) & 0xff);
  129. #ifdef DEBUG
  130. {
  131. u8 current_multiplier, current_voltage;
  132. /* Print voltage and multiplier */
  133. rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
  134. current_voltage = lo & 0xff;
  135. printk(KERN_INFO "eps: Current voltage = %dmV\n",
  136. current_voltage * 16 + 700);
  137. current_multiplier = (lo >> 8) & 0xff;
  138. printk(KERN_INFO "eps: Current multiplier = %d\n",
  139. current_multiplier);
  140. }
  141. #endif
  142. if (err)
  143. freqs.new = freqs.old;
  144. cpufreq_notify_transition(policy, &freqs, CPUFREQ_POSTCHANGE);
  145. return err;
  146. }
  147. static int eps_target(struct cpufreq_policy *policy,
  148. unsigned int target_freq,
  149. unsigned int relation)
  150. {
  151. struct eps_cpu_data *centaur;
  152. unsigned int newstate = 0;
  153. unsigned int cpu = policy->cpu;
  154. unsigned int dest_state;
  155. int ret;
  156. if (unlikely(eps_cpu[cpu] == NULL))
  157. return -ENODEV;
  158. centaur = eps_cpu[cpu];
  159. if (unlikely(cpufreq_frequency_table_target(policy,
  160. &eps_cpu[cpu]->freq_table[0],
  161. target_freq,
  162. relation,
  163. &newstate))) {
  164. return -EINVAL;
  165. }
  166. /* Make frequency transition */
  167. dest_state = centaur->freq_table[newstate].driver_data & 0xffff;
  168. ret = eps_set_state(centaur, policy, dest_state);
  169. if (ret)
  170. printk(KERN_ERR "eps: Timeout!\n");
  171. return ret;
  172. }
  173. static int eps_verify(struct cpufreq_policy *policy)
  174. {
  175. return cpufreq_frequency_table_verify(policy,
  176. &eps_cpu[policy->cpu]->freq_table[0]);
  177. }
  178. static int eps_cpu_init(struct cpufreq_policy *policy)
  179. {
  180. unsigned int i;
  181. u32 lo, hi;
  182. u64 val;
  183. u8 current_multiplier, current_voltage;
  184. u8 max_multiplier, max_voltage;
  185. u8 min_multiplier, min_voltage;
  186. u8 brand = 0;
  187. u32 fsb;
  188. struct eps_cpu_data *centaur;
  189. struct cpuinfo_x86 *c = &cpu_data(0);
  190. struct cpufreq_frequency_table *f_table;
  191. int k, step, voltage;
  192. int ret;
  193. int states;
  194. #if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
  195. unsigned int limit;
  196. #endif
  197. if (policy->cpu != 0)
  198. return -ENODEV;
  199. /* Check brand */
  200. printk(KERN_INFO "eps: Detected VIA ");
  201. switch (c->x86_model) {
  202. case 10:
  203. rdmsr(0x1153, lo, hi);
  204. brand = (((lo >> 2) ^ lo) >> 18) & 3;
  205. printk(KERN_CONT "Model A ");
  206. break;
  207. case 13:
  208. rdmsr(0x1154, lo, hi);
  209. brand = (((lo >> 4) ^ (lo >> 2))) & 0x000000ff;
  210. printk(KERN_CONT "Model D ");
  211. break;
  212. }
  213. switch (brand) {
  214. case EPS_BRAND_C7M:
  215. printk(KERN_CONT "C7-M\n");
  216. break;
  217. case EPS_BRAND_C7:
  218. printk(KERN_CONT "C7\n");
  219. break;
  220. case EPS_BRAND_EDEN:
  221. printk(KERN_CONT "Eden\n");
  222. break;
  223. case EPS_BRAND_C7D:
  224. printk(KERN_CONT "C7-D\n");
  225. break;
  226. case EPS_BRAND_C3:
  227. printk(KERN_CONT "C3\n");
  228. return -ENODEV;
  229. break;
  230. }
  231. /* Enable Enhanced PowerSaver */
  232. rdmsrl(MSR_IA32_MISC_ENABLE, val);
  233. if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
  234. val |= MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP;
  235. wrmsrl(MSR_IA32_MISC_ENABLE, val);
  236. /* Can be locked at 0 */
  237. rdmsrl(MSR_IA32_MISC_ENABLE, val);
  238. if (!(val & MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP)) {
  239. printk(KERN_INFO "eps: Can't enable Enhanced PowerSaver\n");
  240. return -ENODEV;
  241. }
  242. }
  243. /* Print voltage and multiplier */
  244. rdmsr(MSR_IA32_PERF_STATUS, lo, hi);
  245. current_voltage = lo & 0xff;
  246. printk(KERN_INFO "eps: Current voltage = %dmV\n",
  247. current_voltage * 16 + 700);
  248. current_multiplier = (lo >> 8) & 0xff;
  249. printk(KERN_INFO "eps: Current multiplier = %d\n", current_multiplier);
  250. /* Print limits */
  251. max_voltage = hi & 0xff;
  252. printk(KERN_INFO "eps: Highest voltage = %dmV\n",
  253. max_voltage * 16 + 700);
  254. max_multiplier = (hi >> 8) & 0xff;
  255. printk(KERN_INFO "eps: Highest multiplier = %d\n", max_multiplier);
  256. min_voltage = (hi >> 16) & 0xff;
  257. printk(KERN_INFO "eps: Lowest voltage = %dmV\n",
  258. min_voltage * 16 + 700);
  259. min_multiplier = (hi >> 24) & 0xff;
  260. printk(KERN_INFO "eps: Lowest multiplier = %d\n", min_multiplier);
  261. /* Sanity checks */
  262. if (current_multiplier == 0 || max_multiplier == 0
  263. || min_multiplier == 0)
  264. return -EINVAL;
  265. if (current_multiplier > max_multiplier
  266. || max_multiplier <= min_multiplier)
  267. return -EINVAL;
  268. if (current_voltage > 0x1f || max_voltage > 0x1f)
  269. return -EINVAL;
  270. if (max_voltage < min_voltage
  271. || current_voltage < min_voltage
  272. || current_voltage > max_voltage)
  273. return -EINVAL;
  274. /* Check for systems using underclocked CPU */
  275. if (!freq_failsafe_off && max_multiplier != current_multiplier) {
  276. printk(KERN_INFO "eps: Your processor is running at different "
  277. "frequency then its maximum. Aborting.\n");
  278. printk(KERN_INFO "eps: You can use freq_failsafe_off option "
  279. "to disable this check.\n");
  280. return -EINVAL;
  281. }
  282. if (!voltage_failsafe_off && max_voltage != current_voltage) {
  283. printk(KERN_INFO "eps: Your processor is running at different "
  284. "voltage then its maximum. Aborting.\n");
  285. printk(KERN_INFO "eps: You can use voltage_failsafe_off "
  286. "option to disable this check.\n");
  287. return -EINVAL;
  288. }
  289. /* Calc FSB speed */
  290. fsb = cpu_khz / current_multiplier;
  291. #if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
  292. /* Check for ACPI processor speed limit */
  293. if (!ignore_acpi_limit && !eps_acpi_init()) {
  294. if (!acpi_processor_get_bios_limit(policy->cpu, &limit)) {
  295. printk(KERN_INFO "eps: ACPI limit %u.%uGHz\n",
  296. limit/1000000,
  297. (limit%1000000)/10000);
  298. eps_acpi_exit(policy);
  299. /* Check if max_multiplier is in BIOS limits */
  300. if (limit && max_multiplier * fsb > limit) {
  301. printk(KERN_INFO "eps: Aborting.\n");
  302. return -EINVAL;
  303. }
  304. }
  305. }
  306. #endif
  307. /* Allow user to set lower maximum voltage then that reported
  308. * by processor */
  309. if (brand == EPS_BRAND_C7M && set_max_voltage) {
  310. u32 v;
  311. /* Change mV to something hardware can use */
  312. v = (set_max_voltage - 700) / 16;
  313. /* Check if voltage is within limits */
  314. if (v >= min_voltage && v <= max_voltage) {
  315. printk(KERN_INFO "eps: Setting %dmV as maximum.\n",
  316. v * 16 + 700);
  317. max_voltage = v;
  318. }
  319. }
  320. /* Calc number of p-states supported */
  321. if (brand == EPS_BRAND_C7M)
  322. states = max_multiplier - min_multiplier + 1;
  323. else
  324. states = 2;
  325. /* Allocate private data and frequency table for current cpu */
  326. centaur = kzalloc(sizeof(*centaur)
  327. + (states + 1) * sizeof(struct cpufreq_frequency_table),
  328. GFP_KERNEL);
  329. if (!centaur)
  330. return -ENOMEM;
  331. eps_cpu[0] = centaur;
  332. /* Copy basic values */
  333. centaur->fsb = fsb;
  334. #if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
  335. centaur->bios_limit = limit;
  336. #endif
  337. /* Fill frequency and MSR value table */
  338. f_table = &centaur->freq_table[0];
  339. if (brand != EPS_BRAND_C7M) {
  340. f_table[0].frequency = fsb * min_multiplier;
  341. f_table[0].driver_data = (min_multiplier << 8) | min_voltage;
  342. f_table[1].frequency = fsb * max_multiplier;
  343. f_table[1].driver_data = (max_multiplier << 8) | max_voltage;
  344. f_table[2].frequency = CPUFREQ_TABLE_END;
  345. } else {
  346. k = 0;
  347. step = ((max_voltage - min_voltage) * 256)
  348. / (max_multiplier - min_multiplier);
  349. for (i = min_multiplier; i <= max_multiplier; i++) {
  350. voltage = (k * step) / 256 + min_voltage;
  351. f_table[k].frequency = fsb * i;
  352. f_table[k].driver_data = (i << 8) | voltage;
  353. k++;
  354. }
  355. f_table[k].frequency = CPUFREQ_TABLE_END;
  356. }
  357. policy->cpuinfo.transition_latency = 140000; /* 844mV -> 700mV in ns */
  358. policy->cur = fsb * current_multiplier;
  359. ret = cpufreq_frequency_table_cpuinfo(policy, &centaur->freq_table[0]);
  360. if (ret) {
  361. kfree(centaur);
  362. return ret;
  363. }
  364. cpufreq_frequency_table_get_attr(&centaur->freq_table[0], policy->cpu);
  365. return 0;
  366. }
  367. static int eps_cpu_exit(struct cpufreq_policy *policy)
  368. {
  369. unsigned int cpu = policy->cpu;
  370. /* Bye */
  371. cpufreq_frequency_table_put_attr(policy->cpu);
  372. kfree(eps_cpu[cpu]);
  373. eps_cpu[cpu] = NULL;
  374. return 0;
  375. }
  376. static struct freq_attr *eps_attr[] = {
  377. &cpufreq_freq_attr_scaling_available_freqs,
  378. NULL,
  379. };
  380. static struct cpufreq_driver eps_driver = {
  381. .verify = eps_verify,
  382. .target = eps_target,
  383. .init = eps_cpu_init,
  384. .exit = eps_cpu_exit,
  385. .get = eps_get,
  386. .name = "e_powersaver",
  387. .attr = eps_attr,
  388. };
  389. /* This driver will work only on Centaur C7 processors with
  390. * Enhanced SpeedStep/PowerSaver registers */
  391. static const struct x86_cpu_id eps_cpu_id[] = {
  392. { X86_VENDOR_CENTAUR, 6, X86_MODEL_ANY, X86_FEATURE_EST },
  393. {}
  394. };
  395. MODULE_DEVICE_TABLE(x86cpu, eps_cpu_id);
  396. static int __init eps_init(void)
  397. {
  398. if (!x86_match_cpu(eps_cpu_id) || boot_cpu_data.x86_model < 10)
  399. return -ENODEV;
  400. if (cpufreq_register_driver(&eps_driver))
  401. return -EINVAL;
  402. return 0;
  403. }
  404. static void __exit eps_exit(void)
  405. {
  406. cpufreq_unregister_driver(&eps_driver);
  407. }
  408. /* Allow user to overclock his machine or to change frequency to higher after
  409. * unloading module */
  410. module_param(freq_failsafe_off, int, 0644);
  411. MODULE_PARM_DESC(freq_failsafe_off, "Disable current vs max frequency check");
  412. module_param(voltage_failsafe_off, int, 0644);
  413. MODULE_PARM_DESC(voltage_failsafe_off, "Disable current vs max voltage check");
  414. #if defined CONFIG_ACPI_PROCESSOR || defined CONFIG_ACPI_PROCESSOR_MODULE
  415. module_param(ignore_acpi_limit, int, 0644);
  416. MODULE_PARM_DESC(ignore_acpi_limit, "Don't check ACPI's processor speed limit");
  417. #endif
  418. module_param(set_max_voltage, int, 0644);
  419. MODULE_PARM_DESC(set_max_voltage, "Set maximum CPU voltage (mV) C7-M only");
  420. MODULE_AUTHOR("Rafal Bilski <rafalbilski@interia.pl>");
  421. MODULE_DESCRIPTION("Enhanced PowerSaver driver for VIA C7 CPU's.");
  422. MODULE_LICENSE("GPL");
  423. module_init(eps_init);
  424. module_exit(eps_exit);