aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/cpufreq/longhaul.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-05-16 22:17:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-16 22:17:22 -0400
commitd57d39431924d1628ac9b93a2de7f806fc80680a (patch)
tree8d630b5b22333a6368beb3531f20ae5c5eb72229 /drivers/cpufreq/longhaul.c
parent3e21e5dda4907ecb21a124517ab0eb1d176e5231 (diff)
parent27c4a1c5ef61b6d4a9aeae68b24419b4319b97ed (diff)
Merge tag 'pm-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull power management updates from Rafael Wysocki: "The majority of changes go into the cpufreq subsystem this time. To me, quite obviously, the biggest ticket item is the new "schedutil" governor. Interestingly enough, it's the first new cpufreq governor since the beginning of the git era (except for some out-of-the-tree ones). There are two main differences between it and the existing governors. First, it uses the information provided by the scheduler directly for making its decisions, so it doesn't have to track anything by itself. Second, it can invoke drivers (supporting that feature) to adjust CPU performance right away without having to spawn work items to be executed in process context or similar. Currently, the acpi-cpufreq driver is the only one supporting that mode of operation, but then it is used on a large number of systems. The "schedutil" governor as included here is very simple and mostly regarded as a foundation for future work on the integration of the scheduler with CPU power management (in fact, there is work in progress on top of it already). Nevertheless it works and the preliminary results obtained with it are encouraging. There also is some consolidation of CPU frequency management for ARM platforms that can add their machine IDs the the new stub dt-platdev driver now and that will take care of creating the requisite platform device for cpufreq-dt, so it is not necessary to do that in platform code any more. Several ARM platforms are switched over to using this generic mechanism. In addition to that, the intel_pstate driver is now going to respect CPU frequency limits set by the platform firmware (or a BMC) and provided via the ACPI _PPC object. The devfreq subsystem is getting a new "passive" governor for SoCs subsystems that will depend on somebody else to manage their voltage rails and its support for Samsung Exynos SoCs is consolidated. The rest is support for new hardware (Intel Broxton support in intel_idle for one example), bug fixes, optimizations and cleanups in a number of places. Specifics: - New cpufreq "schedutil" governor (making decisions based on CPU utilization information provided by the scheduler and capable of switching CPU frequencies right away if the underlying driver supports that) and support for fast frequency switching in the acpi-cpufreq driver (Rafael Wysocki) - Consolidation of CPU frequency management on ARM platforms allowing them to get rid of some platform-specific boilerplate code if they are going to use the cpufreq-dt driver (Viresh Kumar, Finley Xiao, Marc Gonzalez) - Support for ACPI _PPC and CPU frequency limits in the intel_pstate driver (Srinivas Pandruvada) - Fixes and cleanups in the cpufreq core and generic governor code (Rafael Wysocki, Sai Gurrappadi) - intel_pstate driver optimizations and cleanups (Rafael Wysocki, Philippe Longepe, Chen Yu, Joe Perches) - cpufreq powernv driver fixes and cleanups (Akshay Adiga, Shilpasri Bhat) - cpufreq qoriq driver fixes and cleanups (Jia Hongtao) - ACPI cpufreq driver cleanups (Viresh Kumar) - Assorted cpufreq driver updates (Ashwin Chaugule, Geliang Tang, Javier Martinez Canillas, Paul Gortmaker, Sudeep Holla) - Assorted cpufreq fixes and cleanups (Joe Perches, Arnd Bergmann) - Fixes and cleanups in the OPP (Operating Performance Points) framework, mostly related to OPP sharing, and reorganization of OF-dependent code in it (Viresh Kumar, Arnd Bergmann, Sudeep Holla) - New "passive" governor for devfreq (for SoC subsystems that will rely on someone else for the management of their power resources) and consolidation of devfreq support for Exynos platforms, coding style and typo fixes for devfreq (Chanwoo Choi, MyungJoo Ham) - PM core fixes and cleanups, mostly to make it work better with the generic power domains (genpd) framework, and updates for that framework (Ulf Hansson, Thierry Reding, Colin Ian King) - Intel Broxton support for the intel_idle driver (Len Brown) - cpuidle core optimization and fix (Daniel Lezcano, Dave Gerlach) - ARM cpuidle cleanups (Jisheng Zhang) - Intel Kabylake support for the RAPL power capping driver (Jacob Pan) - AVS (Adaptive Voltage Switching) rockchip-io driver update (Heiko Stuebner) - Updates for the cpupower tool (Arjun Sreedharan, Colin Ian King, Mattia Dongili, Thomas Renninger)" * tag 'pm-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (112 commits) intel_pstate: Clean up get_target_pstate_use_performance() intel_pstate: Use sample.core_avg_perf in get_avg_pstate() intel_pstate: Clarify average performance computation intel_pstate: Avoid unnecessary synchronize_sched() during initialization cpufreq: schedutil: Make default depend on CONFIG_SMP cpufreq: powernv: del_timer_sync when global and local pstate are equal cpufreq: powernv: Move smp_call_function_any() out of irq safe block intel_pstate: Clean up intel_pstate_get() cpufreq: schedutil: Make it depend on CONFIG_SMP cpufreq: governor: Fix handling of special cases in dbs_update() PM / OPP: Move CONFIG_OF dependent code in a separate file cpufreq: intel_pstate: Ignore _PPC processing under HWP cpufreq: arm_big_little: use generic OPP functions for {init, free}_opp_table PM / OPP: add non-OF versions of dev_pm_opp_{cpumask_, }remove_table cpufreq: tango: Use generic platdev driver PM / OPP: pass cpumask by reference cpufreq: Fix GOV_LIMITS handling for the userspace governor cpupower: fix potential memory leak PM / devfreq: style/typo fixes PM / devfreq: exynos: Add the detailed correlation for Exynos5422 bus ..
Diffstat (limited to 'drivers/cpufreq/longhaul.c')
-rw-r--r--drivers/cpufreq/longhaul.c84
1 files changed, 35 insertions, 49 deletions
diff --git a/drivers/cpufreq/longhaul.c b/drivers/cpufreq/longhaul.c
index 247bfa8eaddb..c46a12df40dd 100644
--- a/drivers/cpufreq/longhaul.c
+++ b/drivers/cpufreq/longhaul.c
@@ -21,6 +21,8 @@
21 * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* 21 * BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous*
22 */ 22 */
23 23
24#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
24#include <linux/kernel.h> 26#include <linux/kernel.h>
25#include <linux/module.h> 27#include <linux/module.h>
26#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
@@ -40,8 +42,6 @@
40 42
41#include "longhaul.h" 43#include "longhaul.h"
42 44
43#define PFX "longhaul: "
44
45#define TYPE_LONGHAUL_V1 1 45#define TYPE_LONGHAUL_V1 1
46#define TYPE_LONGHAUL_V2 2 46#define TYPE_LONGHAUL_V2 2
47#define TYPE_POWERSAVER 3 47#define TYPE_POWERSAVER 3
@@ -347,14 +347,13 @@ retry_loop:
347 freqs.new = calc_speed(longhaul_get_cpu_mult()); 347 freqs.new = calc_speed(longhaul_get_cpu_mult());
348 /* Check if requested frequency is set. */ 348 /* Check if requested frequency is set. */
349 if (unlikely(freqs.new != speed)) { 349 if (unlikely(freqs.new != speed)) {
350 printk(KERN_INFO PFX "Failed to set requested frequency!\n"); 350 pr_info("Failed to set requested frequency!\n");
351 /* Revision ID = 1 but processor is expecting revision key 351 /* Revision ID = 1 but processor is expecting revision key
352 * equal to 0. Jumpers at the bottom of processor will change 352 * equal to 0. Jumpers at the bottom of processor will change
353 * multiplier and FSB, but will not change bits in Longhaul 353 * multiplier and FSB, but will not change bits in Longhaul
354 * MSR nor enable voltage scaling. */ 354 * MSR nor enable voltage scaling. */
355 if (!revid_errata) { 355 if (!revid_errata) {
356 printk(KERN_INFO PFX "Enabling \"Ignore Revision ID\" " 356 pr_info("Enabling \"Ignore Revision ID\" option\n");
357 "option.\n");
358 revid_errata = 1; 357 revid_errata = 1;
359 msleep(200); 358 msleep(200);
360 goto retry_loop; 359 goto retry_loop;
@@ -364,11 +363,10 @@ retry_loop:
364 * but it doesn't change frequency. I tried poking various 363 * but it doesn't change frequency. I tried poking various
365 * bits in northbridge registers, but without success. */ 364 * bits in northbridge registers, but without success. */
366 if (longhaul_flags & USE_ACPI_C3) { 365 if (longhaul_flags & USE_ACPI_C3) {
367 printk(KERN_INFO PFX "Disabling ACPI C3 support.\n"); 366 pr_info("Disabling ACPI C3 support\n");
368 longhaul_flags &= ~USE_ACPI_C3; 367 longhaul_flags &= ~USE_ACPI_C3;
369 if (revid_errata) { 368 if (revid_errata) {
370 printk(KERN_INFO PFX "Disabling \"Ignore " 369 pr_info("Disabling \"Ignore Revision ID\" option\n");
371 "Revision ID\" option.\n");
372 revid_errata = 0; 370 revid_errata = 0;
373 } 371 }
374 msleep(200); 372 msleep(200);
@@ -379,7 +377,7 @@ retry_loop:
379 * RevID = 1. RevID errata will make things right. Just 377 * RevID = 1. RevID errata will make things right. Just
380 * to be 100% sure. */ 378 * to be 100% sure. */
381 if (longhaul_version == TYPE_LONGHAUL_V2) { 379 if (longhaul_version == TYPE_LONGHAUL_V2) {
382 printk(KERN_INFO PFX "Switching to Longhaul ver. 1\n"); 380 pr_info("Switching to Longhaul ver. 1\n");
383 longhaul_version = TYPE_LONGHAUL_V1; 381 longhaul_version = TYPE_LONGHAUL_V1;
384 msleep(200); 382 msleep(200);
385 goto retry_loop; 383 goto retry_loop;
@@ -387,8 +385,7 @@ retry_loop:
387 } 385 }
388 386
389 if (!bm_timeout) { 387 if (!bm_timeout) {
390 printk(KERN_INFO PFX "Warning: Timeout while waiting for " 388 pr_info("Warning: Timeout while waiting for idle PCI bus\n");
391 "idle PCI bus.\n");
392 return -EBUSY; 389 return -EBUSY;
393 } 390 }
394 391
@@ -433,12 +430,12 @@ static int longhaul_get_ranges(void)
433 /* Get current frequency */ 430 /* Get current frequency */
434 mult = longhaul_get_cpu_mult(); 431 mult = longhaul_get_cpu_mult();
435 if (mult == -1) { 432 if (mult == -1) {
436 printk(KERN_INFO PFX "Invalid (reserved) multiplier!\n"); 433 pr_info("Invalid (reserved) multiplier!\n");
437 return -EINVAL; 434 return -EINVAL;
438 } 435 }
439 fsb = guess_fsb(mult); 436 fsb = guess_fsb(mult);
440 if (fsb == 0) { 437 if (fsb == 0) {
441 printk(KERN_INFO PFX "Invalid (reserved) FSB!\n"); 438 pr_info("Invalid (reserved) FSB!\n");
442 return -EINVAL; 439 return -EINVAL;
443 } 440 }
444 /* Get max multiplier - as we always did. 441 /* Get max multiplier - as we always did.
@@ -468,11 +465,11 @@ static int longhaul_get_ranges(void)
468 print_speed(highest_speed/1000)); 465 print_speed(highest_speed/1000));
469 466
470 if (lowest_speed == highest_speed) { 467 if (lowest_speed == highest_speed) {
471 printk(KERN_INFO PFX "highestspeed == lowest, aborting.\n"); 468 pr_info("highestspeed == lowest, aborting\n");
472 return -EINVAL; 469 return -EINVAL;
473 } 470 }
474 if (lowest_speed > highest_speed) { 471 if (lowest_speed > highest_speed) {
475 printk(KERN_INFO PFX "nonsense! lowest (%d > %d) !\n", 472 pr_info("nonsense! lowest (%d > %d) !\n",
476 lowest_speed, highest_speed); 473 lowest_speed, highest_speed);
477 return -EINVAL; 474 return -EINVAL;
478 } 475 }
@@ -538,16 +535,16 @@ static void longhaul_setup_voltagescaling(void)
538 535
539 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val); 536 rdmsrl(MSR_VIA_LONGHAUL, longhaul.val);
540 if (!(longhaul.bits.RevisionID & 1)) { 537 if (!(longhaul.bits.RevisionID & 1)) {
541 printk(KERN_INFO PFX "Voltage scaling not supported by CPU.\n"); 538 pr_info("Voltage scaling not supported by CPU\n");
542 return; 539 return;
543 } 540 }
544 541
545 if (!longhaul.bits.VRMRev) { 542 if (!longhaul.bits.VRMRev) {
546 printk(KERN_INFO PFX "VRM 8.5\n"); 543 pr_info("VRM 8.5\n");
547 vrm_mV_table = &vrm85_mV[0]; 544 vrm_mV_table = &vrm85_mV[0];
548 mV_vrm_table = &mV_vrm85[0]; 545 mV_vrm_table = &mV_vrm85[0];
549 } else { 546 } else {
550 printk(KERN_INFO PFX "Mobile VRM\n"); 547 pr_info("Mobile VRM\n");
551 if (cpu_model < CPU_NEHEMIAH) 548 if (cpu_model < CPU_NEHEMIAH)
552 return; 549 return;
553 vrm_mV_table = &mobilevrm_mV[0]; 550 vrm_mV_table = &mobilevrm_mV[0];
@@ -558,27 +555,21 @@ static void longhaul_setup_voltagescaling(void)
558 maxvid = vrm_mV_table[longhaul.bits.MaximumVID]; 555 maxvid = vrm_mV_table[longhaul.bits.MaximumVID];
559 556
560 if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) { 557 if (minvid.mV == 0 || maxvid.mV == 0 || minvid.mV > maxvid.mV) {
561 printk(KERN_INFO PFX "Bogus values Min:%d.%03d Max:%d.%03d. " 558 pr_info("Bogus values Min:%d.%03d Max:%d.%03d - Voltage scaling disabled\n",
562 "Voltage scaling disabled.\n", 559 minvid.mV/1000, minvid.mV%1000,
563 minvid.mV/1000, minvid.mV%1000, 560 maxvid.mV/1000, maxvid.mV%1000);
564 maxvid.mV/1000, maxvid.mV%1000);
565 return; 561 return;
566 } 562 }
567 563
568 if (minvid.mV == maxvid.mV) { 564 if (minvid.mV == maxvid.mV) {
569 printk(KERN_INFO PFX "Claims to support voltage scaling but " 565 pr_info("Claims to support voltage scaling but min & max are both %d.%03d - Voltage scaling disabled\n",
570 "min & max are both %d.%03d. " 566 maxvid.mV/1000, maxvid.mV%1000);
571 "Voltage scaling disabled\n",
572 maxvid.mV/1000, maxvid.mV%1000);
573 return; 567 return;
574 } 568 }
575 569
576 /* How many voltage steps*/ 570 /* How many voltage steps*/
577 numvscales = maxvid.pos - minvid.pos + 1; 571 numvscales = maxvid.pos - minvid.pos + 1;
578 printk(KERN_INFO PFX 572 pr_info("Max VID=%d.%03d Min VID=%d.%03d, %d possible voltage scales\n",
579 "Max VID=%d.%03d "
580 "Min VID=%d.%03d, "
581 "%d possible voltage scales\n",
582 maxvid.mV/1000, maxvid.mV%1000, 573 maxvid.mV/1000, maxvid.mV%1000,
583 minvid.mV/1000, minvid.mV%1000, 574 minvid.mV/1000, minvid.mV%1000,
584 numvscales); 575 numvscales);
@@ -617,12 +608,12 @@ static void longhaul_setup_voltagescaling(void)
617 pos = minvid.pos; 608 pos = minvid.pos;
618 freq_pos->driver_data |= mV_vrm_table[pos] << 8; 609 freq_pos->driver_data |= mV_vrm_table[pos] << 8;
619 vid = vrm_mV_table[mV_vrm_table[pos]]; 610 vid = vrm_mV_table[mV_vrm_table[pos]];
620 printk(KERN_INFO PFX "f: %d kHz, index: %d, vid: %d mV\n", 611 pr_info("f: %d kHz, index: %d, vid: %d mV\n",
621 speed, (int)(freq_pos - longhaul_table), vid.mV); 612 speed, (int)(freq_pos - longhaul_table), vid.mV);
622 } 613 }
623 614
624 can_scale_voltage = 1; 615 can_scale_voltage = 1;
625 printk(KERN_INFO PFX "Voltage scaling enabled.\n"); 616 pr_info("Voltage scaling enabled\n");
626} 617}
627 618
628 619
@@ -720,8 +711,7 @@ static int enable_arbiter_disable(void)
720 pci_write_config_byte(dev, reg, pci_cmd); 711 pci_write_config_byte(dev, reg, pci_cmd);
721 pci_read_config_byte(dev, reg, &pci_cmd); 712 pci_read_config_byte(dev, reg, &pci_cmd);
722 if (!(pci_cmd & 1<<7)) { 713 if (!(pci_cmd & 1<<7)) {
723 printk(KERN_ERR PFX 714 pr_err("Can't enable access to port 0x22\n");
724 "Can't enable access to port 0x22.\n");
725 status = 0; 715 status = 0;
726 } 716 }
727 } 717 }
@@ -758,8 +748,7 @@ static int longhaul_setup_southbridge(void)
758 if (pci_cmd & 1 << 7) { 748 if (pci_cmd & 1 << 7) {
759 pci_read_config_dword(dev, 0x88, &acpi_regs_addr); 749 pci_read_config_dword(dev, 0x88, &acpi_regs_addr);
760 acpi_regs_addr &= 0xff00; 750 acpi_regs_addr &= 0xff00;
761 printk(KERN_INFO PFX "ACPI I/O at 0x%x\n", 751 pr_info("ACPI I/O at 0x%x\n", acpi_regs_addr);
762 acpi_regs_addr);
763 } 752 }
764 753
765 pci_dev_put(dev); 754 pci_dev_put(dev);
@@ -853,14 +842,14 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
853 longhaul_version = TYPE_LONGHAUL_V1; 842 longhaul_version = TYPE_LONGHAUL_V1;
854 } 843 }
855 844
856 printk(KERN_INFO PFX "VIA %s CPU detected. ", cpuname); 845 pr_info("VIA %s CPU detected. ", cpuname);
857 switch (longhaul_version) { 846 switch (longhaul_version) {
858 case TYPE_LONGHAUL_V1: 847 case TYPE_LONGHAUL_V1:
859 case TYPE_LONGHAUL_V2: 848 case TYPE_LONGHAUL_V2:
860 printk(KERN_CONT "Longhaul v%d supported.\n", longhaul_version); 849 pr_cont("Longhaul v%d supported\n", longhaul_version);
861 break; 850 break;
862 case TYPE_POWERSAVER: 851 case TYPE_POWERSAVER:
863 printk(KERN_CONT "Powersaver supported.\n"); 852 pr_cont("Powersaver supported\n");
864 break; 853 break;
865 }; 854 };
866 855
@@ -889,15 +878,14 @@ static int longhaul_cpu_init(struct cpufreq_policy *policy)
889 if (!(longhaul_flags & USE_ACPI_C3 878 if (!(longhaul_flags & USE_ACPI_C3
890 || longhaul_flags & USE_NORTHBRIDGE) 879 || longhaul_flags & USE_NORTHBRIDGE)
891 && ((pr == NULL) || !(pr->flags.bm_control))) { 880 && ((pr == NULL) || !(pr->flags.bm_control))) {
892 printk(KERN_ERR PFX 881 pr_err("No ACPI support: Unsupported northbridge\n");
893 "No ACPI support. Unsupported northbridge.\n");
894 return -ENODEV; 882 return -ENODEV;
895 } 883 }
896 884
897 if (longhaul_flags & USE_NORTHBRIDGE) 885 if (longhaul_flags & USE_NORTHBRIDGE)
898 printk(KERN_INFO PFX "Using northbridge support.\n"); 886 pr_info("Using northbridge support\n");
899 if (longhaul_flags & USE_ACPI_C3) 887 if (longhaul_flags & USE_ACPI_C3)
900 printk(KERN_INFO PFX "Using ACPI support.\n"); 888 pr_info("Using ACPI support\n");
901 889
902 ret = longhaul_get_ranges(); 890 ret = longhaul_get_ranges();
903 if (ret != 0) 891 if (ret != 0)
@@ -934,20 +922,18 @@ static int __init longhaul_init(void)
934 return -ENODEV; 922 return -ENODEV;
935 923
936 if (!enable) { 924 if (!enable) {
937 printk(KERN_ERR PFX "Option \"enable\" not set. Aborting.\n"); 925 pr_err("Option \"enable\" not set - Aborting\n");
938 return -ENODEV; 926 return -ENODEV;
939 } 927 }
940#ifdef CONFIG_SMP 928#ifdef CONFIG_SMP
941 if (num_online_cpus() > 1) { 929 if (num_online_cpus() > 1) {
942 printk(KERN_ERR PFX "More than 1 CPU detected, " 930 pr_err("More than 1 CPU detected, longhaul disabled\n");
943 "longhaul disabled.\n");
944 return -ENODEV; 931 return -ENODEV;
945 } 932 }
946#endif 933#endif
947#ifdef CONFIG_X86_IO_APIC 934#ifdef CONFIG_X86_IO_APIC
948 if (boot_cpu_has(X86_FEATURE_APIC)) { 935 if (boot_cpu_has(X86_FEATURE_APIC)) {
949 printk(KERN_ERR PFX "APIC detected. Longhaul is currently " 936 pr_err("APIC detected. Longhaul is currently broken in this configuration.\n");
950 "broken in this configuration.\n");
951 return -ENODEV; 937 return -ENODEV;
952 } 938 }
953#endif 939#endif
@@ -955,7 +941,7 @@ static int __init longhaul_init(void)
955 case 6 ... 9: 941 case 6 ... 9:
956 return cpufreq_register_driver(&longhaul_driver); 942 return cpufreq_register_driver(&longhaul_driver);
957 case 10: 943 case 10:
958 printk(KERN_ERR PFX "Use acpi-cpufreq driver for VIA C7\n"); 944 pr_err("Use acpi-cpufreq driver for VIA C7\n");
959 default: 945 default:
960 ; 946 ;
961 } 947 }