1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29#include <linux/kernel.h>
30#include <linux/module.h>
31#include <linux/init.h>
32#include <linux/cpufreq.h>
33#include <linux/slab.h>
34#include <linux/acpi.h>
35#include <acpi/processor.h>
36#ifdef CONFIG_X86
37#include <asm/cpufeature.h>
38#endif
39
40#define PREFIX "ACPI: "
41
42#define ACPI_PROCESSOR_CLASS "processor"
43#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
44#define _COMPONENT ACPI_PROCESSOR_COMPONENT
45ACPI_MODULE_NAME("processor_perflib");
46
47static DEFINE_MUTEX(performance_mutex);
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65static int ignore_ppc = -1;
66module_param(ignore_ppc, int, 0644);
67MODULE_PARM_DESC(ignore_ppc, "If the frequency of your machine gets wrongly" \
68 "limited by BIOS, this should help");
69
70#define PPC_REGISTERED 1
71#define PPC_IN_USE 2
72
73static int acpi_processor_ppc_status;
74
75static int acpi_processor_ppc_notifier(struct notifier_block *nb,
76 unsigned long event, void *data)
77{
78 struct cpufreq_policy *policy = data;
79 struct acpi_processor *pr;
80 unsigned int ppc = 0;
81
82 if (event == CPUFREQ_START && ignore_ppc <= 0) {
83 ignore_ppc = 0;
84 return 0;
85 }
86
87 if (ignore_ppc)
88 return 0;
89
90 if (event != CPUFREQ_INCOMPATIBLE)
91 return 0;
92
93 mutex_lock(&performance_mutex);
94
95 pr = per_cpu(processors, policy->cpu);
96 if (!pr || !pr->performance)
97 goto out;
98
99 ppc = (unsigned int)pr->performance_platform_limit;
100
101 if (ppc >= pr->performance->state_count)
102 goto out;
103
104 cpufreq_verify_within_limits(policy, 0,
105 pr->performance->states[ppc].
106 core_frequency * 1000);
107
108 out:
109 mutex_unlock(&performance_mutex);
110
111 return 0;
112}
113
114static struct notifier_block acpi_ppc_notifier_block = {
115 .notifier_call = acpi_processor_ppc_notifier,
116};
117
118static int acpi_processor_get_platform_limit(struct acpi_processor *pr)
119{
120 acpi_status status = 0;
121 unsigned long long ppc = 0;
122
123
124 if (!pr)
125 return -EINVAL;
126
127
128
129
130
131 status = acpi_evaluate_integer(pr->handle, "_PPC", NULL, &ppc);
132
133 if (status != AE_NOT_FOUND)
134 acpi_processor_ppc_status |= PPC_IN_USE;
135
136 if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) {
137 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PPC"));
138 return -ENODEV;
139 }
140
141 pr_debug("CPU %d: _PPC is %d - frequency %s limited\n", pr->id,
142 (int)ppc, ppc ? "" : "not");
143
144 pr->performance_platform_limit = (int)ppc;
145
146 return 0;
147}
148
149#define ACPI_PROCESSOR_NOTIFY_PERFORMANCE 0x80
150
151
152
153
154
155
156
157static void acpi_processor_ppc_ost(acpi_handle handle, int status)
158{
159 union acpi_object params[2] = {
160 {.type = ACPI_TYPE_INTEGER,},
161 {.type = ACPI_TYPE_INTEGER,},
162 };
163 struct acpi_object_list arg_list = {2, params};
164
165 if (acpi_has_method(handle, "_OST")) {
166 params[0].integer.value = ACPI_PROCESSOR_NOTIFY_PERFORMANCE;
167 params[1].integer.value = status;
168 acpi_evaluate_object(handle, "_OST", &arg_list, NULL);
169 }
170}
171
172int acpi_processor_ppc_has_changed(struct acpi_processor *pr, int event_flag)
173{
174 int ret;
175
176 if (ignore_ppc) {
177
178
179
180
181 if (event_flag)
182 acpi_processor_ppc_ost(pr->handle, 1);
183 return 0;
184 }
185
186 ret = acpi_processor_get_platform_limit(pr);
187
188
189
190
191 if (event_flag) {
192 if (ret < 0)
193 acpi_processor_ppc_ost(pr->handle, 1);
194 else
195 acpi_processor_ppc_ost(pr->handle, 0);
196 }
197 if (ret < 0)
198 return (ret);
199 else
200 return cpufreq_update_policy(pr->id);
201}
202
203int acpi_processor_get_bios_limit(int cpu, unsigned int *limit)
204{
205 struct acpi_processor *pr;
206
207 pr = per_cpu(processors, cpu);
208 if (!pr || !pr->performance || !pr->performance->state_count)
209 return -ENODEV;
210 *limit = pr->performance->states[pr->performance_platform_limit].
211 core_frequency * 1000;
212 return 0;
213}
214EXPORT_SYMBOL(acpi_processor_get_bios_limit);
215
216void acpi_processor_ppc_init(void)
217{
218 if (!cpufreq_register_notifier
219 (&acpi_ppc_notifier_block, CPUFREQ_POLICY_NOTIFIER))
220 acpi_processor_ppc_status |= PPC_REGISTERED;
221 else
222 printk(KERN_DEBUG
223 "Warning: Processor Platform Limit not supported.\n");
224}
225
226void acpi_processor_ppc_exit(void)
227{
228 if (acpi_processor_ppc_status & PPC_REGISTERED)
229 cpufreq_unregister_notifier(&acpi_ppc_notifier_block,
230 CPUFREQ_POLICY_NOTIFIER);
231
232 acpi_processor_ppc_status &= ~PPC_REGISTERED;
233}
234
235static int acpi_processor_get_performance_control(struct acpi_processor *pr)
236{
237 int result = 0;
238 acpi_status status = 0;
239 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
240 union acpi_object *pct = NULL;
241 union acpi_object obj = { 0 };
242
243
244 status = acpi_evaluate_object(pr->handle, "_PCT", NULL, &buffer);
245 if (ACPI_FAILURE(status)) {
246 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PCT"));
247 return -ENODEV;
248 }
249
250 pct = (union acpi_object *)buffer.pointer;
251 if (!pct || (pct->type != ACPI_TYPE_PACKAGE)
252 || (pct->package.count != 2)) {
253 printk(KERN_ERR PREFIX "Invalid _PCT data\n");
254 result = -EFAULT;
255 goto end;
256 }
257
258
259
260
261
262 obj = pct->package.elements[0];
263
264 if ((obj.type != ACPI_TYPE_BUFFER)
265 || (obj.buffer.length < sizeof(struct acpi_pct_register))
266 || (obj.buffer.pointer == NULL)) {
267 printk(KERN_ERR PREFIX "Invalid _PCT data (control_register)\n");
268 result = -EFAULT;
269 goto end;
270 }
271 memcpy(&pr->performance->control_register, obj.buffer.pointer,
272 sizeof(struct acpi_pct_register));
273
274
275
276
277
278 obj = pct->package.elements[1];
279
280 if ((obj.type != ACPI_TYPE_BUFFER)
281 || (obj.buffer.length < sizeof(struct acpi_pct_register))
282 || (obj.buffer.pointer == NULL)) {
283 printk(KERN_ERR PREFIX "Invalid _PCT data (status_register)\n");
284 result = -EFAULT;
285 goto end;
286 }
287
288 memcpy(&pr->performance->status_register, obj.buffer.pointer,
289 sizeof(struct acpi_pct_register));
290
291 end:
292 kfree(buffer.pointer);
293
294 return result;
295}
296
297#ifdef CONFIG_X86
298
299
300
301
302static void amd_fixup_frequency(struct acpi_processor_px *px, int i)
303{
304 u32 hi, lo, fid, did;
305 int index = px->control & 0x00000007;
306
307 if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
308 return;
309
310 if ((boot_cpu_data.x86 == 0x10 && boot_cpu_data.x86_model < 10)
311 || boot_cpu_data.x86 == 0x11) {
312 rdmsr(MSR_AMD_PSTATE_DEF_BASE + index, lo, hi);
313
314
315
316
317 if (!(hi & BIT(31)))
318 return;
319
320 fid = lo & 0x3f;
321 did = (lo >> 6) & 7;
322 if (boot_cpu_data.x86 == 0x10)
323 px->core_frequency = (100 * (fid + 0x10)) >> did;
324 else
325 px->core_frequency = (100 * (fid + 8)) >> did;
326 }
327}
328#else
329static void amd_fixup_frequency(struct acpi_processor_px *px, int i) {};
330#endif
331
332static int acpi_processor_get_performance_states(struct acpi_processor *pr)
333{
334 int result = 0;
335 acpi_status status = AE_OK;
336 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
337 struct acpi_buffer format = { sizeof("NNNNNN"), "NNNNNN" };
338 struct acpi_buffer state = { 0, NULL };
339 union acpi_object *pss = NULL;
340 int i;
341 int last_invalid = -1;
342
343
344 status = acpi_evaluate_object(pr->handle, "_PSS", NULL, &buffer);
345 if (ACPI_FAILURE(status)) {
346 ACPI_EXCEPTION((AE_INFO, status, "Evaluating _PSS"));
347 return -ENODEV;
348 }
349
350 pss = buffer.pointer;
351 if (!pss || (pss->type != ACPI_TYPE_PACKAGE)) {
352 printk(KERN_ERR PREFIX "Invalid _PSS data\n");
353 result = -EFAULT;
354 goto end;
355 }
356
357 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Found %d performance states\n",
358 pss->package.count));
359
360 pr->performance->state_count = pss->package.count;
361 pr->performance->states =
362 kmalloc(sizeof(struct acpi_processor_px) * pss->package.count,
363 GFP_KERNEL);
364 if (!pr->performance->states) {
365 result = -ENOMEM;
366 goto end;
367 }
368
369 for (i = 0; i < pr->performance->state_count; i++) {
370
371 struct acpi_processor_px *px = &(pr->performance->states[i]);
372
373 state.length = sizeof(struct acpi_processor_px);
374 state.pointer = px;
375
376 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Extracting state %d\n", i));
377
378 status = acpi_extract_package(&(pss->package.elements[i]),
379 &format, &state);
380 if (ACPI_FAILURE(status)) {
381 ACPI_EXCEPTION((AE_INFO, status, "Invalid _PSS data"));
382 result = -EFAULT;
383 kfree(pr->performance->states);
384 goto end;
385 }
386
387 amd_fixup_frequency(px, i);
388
389 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
390 "State [%d]: core_frequency[%d] power[%d] transition_latency[%d] bus_master_latency[%d] control[0x%x] status[0x%x]\n",
391 i,
392 (u32) px->core_frequency,
393 (u32) px->power,
394 (u32) px->transition_latency,
395 (u32) px->bus_master_latency,
396 (u32) px->control, (u32) px->status));
397
398
399
400
401 if (!px->core_frequency ||
402 ((u32)(px->core_frequency * 1000) !=
403 (px->core_frequency * 1000))) {
404 printk(KERN_ERR FW_BUG PREFIX
405 "Invalid BIOS _PSS frequency found for processor %d: 0x%llx MHz\n",
406 pr->id, px->core_frequency);
407 if (last_invalid == -1)
408 last_invalid = i;
409 } else {
410 if (last_invalid != -1) {
411
412
413
414 memcpy(&(pr->performance->states[last_invalid]),
415 px, sizeof(struct acpi_processor_px));
416 ++last_invalid;
417 }
418 }
419 }
420
421 if (last_invalid == 0) {
422 printk(KERN_ERR FW_BUG PREFIX
423 "No valid BIOS _PSS frequency found for processor %d\n", pr->id);
424 result = -EFAULT;
425 kfree(pr->performance->states);
426 pr->performance->states = NULL;
427 }
428
429 if (last_invalid > 0)
430 pr->performance->state_count = last_invalid;
431
432 end:
433 kfree(buffer.pointer);
434
435 return result;
436}
437
438int acpi_processor_get_performance_info(struct acpi_processor *pr)
439{
440 int result = 0;
441
442 if (!pr || !pr->performance || !pr->handle)
443 return -EINVAL;
444
445 if (!acpi_has_method(pr->handle, "_PCT")) {
446 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
447 "ACPI-based processor performance control unavailable\n"));
448 return -ENODEV;
449 }
450
451 result = acpi_processor_get_performance_control(pr);
452 if (result)
453 goto update_bios;
454
455 result = acpi_processor_get_performance_states(pr);
456 if (result)
457 goto update_bios;
458
459
460 if (ignore_ppc != 1)
461 result = acpi_processor_get_platform_limit(pr);
462
463 return result;
464
465
466
467
468
469 update_bios:
470#ifdef CONFIG_X86
471 if (acpi_has_method(pr->handle, "_PPC")) {
472 if(boot_cpu_has(X86_FEATURE_EST))
473 printk(KERN_WARNING FW_BUG "BIOS needs update for CPU "
474 "frequency support\n");
475 }
476#endif
477 return result;
478}
479EXPORT_SYMBOL_GPL(acpi_processor_get_performance_info);
480int acpi_processor_notify_smm(struct module *calling_module)
481{
482 acpi_status status;
483 static int is_done = 0;
484
485
486 if (!(acpi_processor_ppc_status & PPC_REGISTERED))
487 return -EBUSY;
488
489 if (!try_module_get(calling_module))
490 return -EINVAL;
491
492
493
494
495
496
497 if (is_done > 0) {
498 module_put(calling_module);
499 return 0;
500 } else if (is_done < 0) {
501 module_put(calling_module);
502 return is_done;
503 }
504
505 is_done = -EIO;
506
507
508 if ((!acpi_gbl_FADT.smi_command) || (!acpi_gbl_FADT.pstate_control)) {
509 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No SMI port or pstate_control\n"));
510 module_put(calling_module);
511 return 0;
512 }
513
514 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
515 "Writing pstate_control [0x%x] to smi_command [0x%x]\n",
516 acpi_gbl_FADT.pstate_control, acpi_gbl_FADT.smi_command));
517
518 status = acpi_os_write_port(acpi_gbl_FADT.smi_command,
519 (u32) acpi_gbl_FADT.pstate_control, 8);
520 if (ACPI_FAILURE(status)) {
521 ACPI_EXCEPTION((AE_INFO, status,
522 "Failed to write pstate_control [0x%x] to "
523 "smi_command [0x%x]", acpi_gbl_FADT.pstate_control,
524 acpi_gbl_FADT.smi_command));
525 module_put(calling_module);
526 return status;
527 }
528
529
530
531 is_done = 1;
532
533 if (!(acpi_processor_ppc_status & PPC_IN_USE))
534 module_put(calling_module);
535
536 return 0;
537}
538
539EXPORT_SYMBOL(acpi_processor_notify_smm);
540
541static int acpi_processor_get_psd(struct acpi_processor *pr)
542{
543 int result = 0;
544 acpi_status status = AE_OK;
545 struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL};
546 struct acpi_buffer format = {sizeof("NNNNN"), "NNNNN"};
547 struct acpi_buffer state = {0, NULL};
548 union acpi_object *psd = NULL;
549 struct acpi_psd_package *pdomain;
550
551 status = acpi_evaluate_object(pr->handle, "_PSD", NULL, &buffer);
552 if (ACPI_FAILURE(status)) {
553 return -ENODEV;
554 }
555
556 psd = buffer.pointer;
557 if (!psd || (psd->type != ACPI_TYPE_PACKAGE)) {
558 printk(KERN_ERR PREFIX "Invalid _PSD data\n");
559 result = -EFAULT;
560 goto end;
561 }
562
563 if (psd->package.count != 1) {
564 printk(KERN_ERR PREFIX "Invalid _PSD data\n");
565 result = -EFAULT;
566 goto end;
567 }
568
569 pdomain = &(pr->performance->domain_info);
570
571 state.length = sizeof(struct acpi_psd_package);
572 state.pointer = pdomain;
573
574 status = acpi_extract_package(&(psd->package.elements[0]),
575 &format, &state);
576 if (ACPI_FAILURE(status)) {
577 printk(KERN_ERR PREFIX "Invalid _PSD data\n");
578 result = -EFAULT;
579 goto end;
580 }
581
582 if (pdomain->num_entries != ACPI_PSD_REV0_ENTRIES) {
583 printk(KERN_ERR PREFIX "Unknown _PSD:num_entries\n");
584 result = -EFAULT;
585 goto end;
586 }
587
588 if (pdomain->revision != ACPI_PSD_REV0_REVISION) {
589 printk(KERN_ERR PREFIX "Unknown _PSD:revision\n");
590 result = -EFAULT;
591 goto end;
592 }
593
594 if (pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ALL &&
595 pdomain->coord_type != DOMAIN_COORD_TYPE_SW_ANY &&
596 pdomain->coord_type != DOMAIN_COORD_TYPE_HW_ALL) {
597 printk(KERN_ERR PREFIX "Invalid _PSD:coord_type\n");
598 result = -EFAULT;
599 goto end;
600 }
601end:
602 kfree(buffer.pointer);
603 return result;
604}
605
606int acpi_processor_preregister_performance(
607 struct acpi_processor_performance __percpu *performance)
608{
609 int count_target;
610 int retval = 0;
611 unsigned int i, j;
612 cpumask_var_t covered_cpus;
613 struct acpi_processor *pr;
614 struct acpi_psd_package *pdomain;
615 struct acpi_processor *match_pr;
616 struct acpi_psd_package *match_pdomain;
617
618 if (!zalloc_cpumask_var(&covered_cpus, GFP_KERNEL))
619 return -ENOMEM;
620
621 mutex_lock(&performance_mutex);
622
623
624
625
626
627 for_each_possible_cpu(i) {
628 pr = per_cpu(processors, i);
629 if (!pr) {
630
631 continue;
632 }
633
634 if (pr->performance) {
635 retval = -EBUSY;
636 goto err_out;
637 }
638
639 if (!performance || !per_cpu_ptr(performance, i)) {
640 retval = -EINVAL;
641 goto err_out;
642 }
643 }
644
645
646 for_each_possible_cpu(i) {
647 pr = per_cpu(processors, i);
648 if (!pr)
649 continue;
650
651 pr->performance = per_cpu_ptr(performance, i);
652 cpumask_set_cpu(i, pr->performance->shared_cpu_map);
653 if (acpi_processor_get_psd(pr)) {
654 retval = -EINVAL;
655 continue;
656 }
657 }
658 if (retval)
659 goto err_ret;
660
661
662
663
664
665 for_each_possible_cpu(i) {
666 pr = per_cpu(processors, i);
667 if (!pr)
668 continue;
669
670 if (cpumask_test_cpu(i, covered_cpus))
671 continue;
672
673 pdomain = &(pr->performance->domain_info);
674 cpumask_set_cpu(i, pr->performance->shared_cpu_map);
675 cpumask_set_cpu(i, covered_cpus);
676 if (pdomain->num_processors <= 1)
677 continue;
678
679
680 count_target = pdomain->num_processors;
681 if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
682 pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
683 else if (pdomain->coord_type == DOMAIN_COORD_TYPE_HW_ALL)
684 pr->performance->shared_type = CPUFREQ_SHARED_TYPE_HW;
685 else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY)
686 pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ANY;
687
688 for_each_possible_cpu(j) {
689 if (i == j)
690 continue;
691
692 match_pr = per_cpu(processors, j);
693 if (!match_pr)
694 continue;
695
696 match_pdomain = &(match_pr->performance->domain_info);
697 if (match_pdomain->domain != pdomain->domain)
698 continue;
699
700
701
702 if (match_pdomain->num_processors != count_target) {
703 retval = -EINVAL;
704 goto err_ret;
705 }
706
707 if (pdomain->coord_type != match_pdomain->coord_type) {
708 retval = -EINVAL;
709 goto err_ret;
710 }
711
712 cpumask_set_cpu(j, covered_cpus);
713 cpumask_set_cpu(j, pr->performance->shared_cpu_map);
714 }
715
716 for_each_possible_cpu(j) {
717 if (i == j)
718 continue;
719
720 match_pr = per_cpu(processors, j);
721 if (!match_pr)
722 continue;
723
724 match_pdomain = &(match_pr->performance->domain_info);
725 if (match_pdomain->domain != pdomain->domain)
726 continue;
727
728 match_pr->performance->shared_type =
729 pr->performance->shared_type;
730 cpumask_copy(match_pr->performance->shared_cpu_map,
731 pr->performance->shared_cpu_map);
732 }
733 }
734
735err_ret:
736 for_each_possible_cpu(i) {
737 pr = per_cpu(processors, i);
738 if (!pr || !pr->performance)
739 continue;
740
741
742 if (retval) {
743 cpumask_clear(pr->performance->shared_cpu_map);
744 cpumask_set_cpu(i, pr->performance->shared_cpu_map);
745 pr->performance->shared_type = CPUFREQ_SHARED_TYPE_ALL;
746 }
747 pr->performance = NULL;
748 }
749
750err_out:
751 mutex_unlock(&performance_mutex);
752 free_cpumask_var(covered_cpus);
753 return retval;
754}
755EXPORT_SYMBOL(acpi_processor_preregister_performance);
756
757int
758acpi_processor_register_performance(struct acpi_processor_performance
759 *performance, unsigned int cpu)
760{
761 struct acpi_processor *pr;
762
763 if (!(acpi_processor_ppc_status & PPC_REGISTERED))
764 return -EINVAL;
765
766 mutex_lock(&performance_mutex);
767
768 pr = per_cpu(processors, cpu);
769 if (!pr) {
770 mutex_unlock(&performance_mutex);
771 return -ENODEV;
772 }
773
774 if (pr->performance) {
775 mutex_unlock(&performance_mutex);
776 return -EBUSY;
777 }
778
779 WARN_ON(!performance);
780
781 pr->performance = performance;
782
783 if (acpi_processor_get_performance_info(pr)) {
784 pr->performance = NULL;
785 mutex_unlock(&performance_mutex);
786 return -EIO;
787 }
788
789 mutex_unlock(&performance_mutex);
790 return 0;
791}
792
793EXPORT_SYMBOL(acpi_processor_register_performance);
794
795void
796acpi_processor_unregister_performance(struct acpi_processor_performance
797 *performance, unsigned int cpu)
798{
799 struct acpi_processor *pr;
800
801 mutex_lock(&performance_mutex);
802
803 pr = per_cpu(processors, cpu);
804 if (!pr) {
805 mutex_unlock(&performance_mutex);
806 return;
807 }
808
809 if (pr->performance)
810 kfree(pr->performance->states);
811 pr->performance = NULL;
812
813 mutex_unlock(&performance_mutex);
814
815 return;
816}
817
818EXPORT_SYMBOL(acpi_processor_unregister_performance);
819