diff options
author | Jacob Pan <jacob.jun.pan@linux.intel.com> | 2014-11-07 12:29:25 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2014-11-11 17:40:06 -0500 |
commit | 087e9cbab5022f8bb6dc9574ff5e320569903b80 (patch) | |
tree | 76d90b7d57a6e8ef2f159f34903fc5f1a95c9194 /drivers/powercap/intel_rapl.c | |
parent | 206c5f60a3d902bc4b56dab2de3e88de5eb06108 (diff) |
powercap / RAPL: abstract per cpu type functions
RAPL implementations may vary slightly between Core and Atom CPUs. There are
also potential differences among generations of CPUs within the family.
This patch adds a per model structure to abstract the differences such that
variations can be handled cleanly.
Signed-off-by: Jacob Pan <jacob.jun.pan@linux.intel.com>
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Diffstat (limited to 'drivers/powercap/intel_rapl.c')
-rw-r--r-- | drivers/powercap/intel_rapl.c | 45 |
1 files changed, 35 insertions, 10 deletions
diff --git a/drivers/powercap/intel_rapl.c b/drivers/powercap/intel_rapl.c index 45e05b32f9b6..256efed5b88f 100644 --- a/drivers/powercap/intel_rapl.c +++ b/drivers/powercap/intel_rapl.c | |||
@@ -188,6 +188,15 @@ struct rapl_package { | |||
188 | */ | 188 | */ |
189 | struct list_head plist; | 189 | struct list_head plist; |
190 | }; | 190 | }; |
191 | |||
192 | struct rapl_defaults { | ||
193 | int (*check_unit)(struct rapl_package *rp, int cpu); | ||
194 | void (*set_floor_freq)(struct rapl_domain *rd, bool mode); | ||
195 | u64 (*compute_time_window)(struct rapl_package *rp, u64 val, | ||
196 | bool to_raw); | ||
197 | }; | ||
198 | static struct rapl_defaults *rapl_defaults; | ||
199 | |||
191 | #define PACKAGE_PLN_INT_SAVED BIT(0) | 200 | #define PACKAGE_PLN_INT_SAVED BIT(0) |
192 | #define MAX_PRIM_NAME (32) | 201 | #define MAX_PRIM_NAME (32) |
193 | 202 | ||
@@ -946,16 +955,28 @@ static void package_power_limit_irq_restore(int package_id) | |||
946 | wrmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h); | 955 | wrmsr_on_cpu(cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT, l, h); |
947 | } | 956 | } |
948 | 957 | ||
958 | static const struct rapl_defaults rapl_defaults_core = { | ||
959 | }; | ||
960 | |||
961 | static const struct rapl_defaults rapl_defaults_atom = { | ||
962 | }; | ||
963 | |||
964 | #define RAPL_CPU(_model, _ops) { \ | ||
965 | .vendor = X86_VENDOR_INTEL, \ | ||
966 | .family = 6, \ | ||
967 | .model = _model, \ | ||
968 | .driver_data = (kernel_ulong_t)&_ops, \ | ||
969 | } | ||
970 | |||
949 | static const struct x86_cpu_id rapl_ids[] = { | 971 | static const struct x86_cpu_id rapl_ids[] = { |
950 | { X86_VENDOR_INTEL, 6, 0x2a},/* Sandy Bridge */ | 972 | RAPL_CPU(0x2a, rapl_defaults_core),/* Sandy Bridge */ |
951 | { X86_VENDOR_INTEL, 6, 0x2d},/* Sandy Bridge EP */ | 973 | RAPL_CPU(0x2d, rapl_defaults_core),/* Sandy Bridge EP */ |
952 | { X86_VENDOR_INTEL, 6, 0x37},/* Valleyview */ | 974 | RAPL_CPU(0x37, rapl_defaults_atom),/* Valleyview */ |
953 | { X86_VENDOR_INTEL, 6, 0x3a},/* Ivy Bridge */ | 975 | RAPL_CPU(0x3a, rapl_defaults_core),/* Ivy Bridge */ |
954 | { X86_VENDOR_INTEL, 6, 0x3c},/* Haswell */ | 976 | RAPL_CPU(0x3c, rapl_defaults_core),/* Haswell */ |
955 | { X86_VENDOR_INTEL, 6, 0x3d},/* Broadwell */ | 977 | RAPL_CPU(0x3d, rapl_defaults_core),/* Broadwell */ |
956 | { X86_VENDOR_INTEL, 6, 0x3f},/* Haswell */ | 978 | RAPL_CPU(0x3f, rapl_defaults_core),/* Haswell */ |
957 | { X86_VENDOR_INTEL, 6, 0x45},/* Haswell ULT */ | 979 | RAPL_CPU(0x45, rapl_defaults_core),/* Haswell ULT */ |
958 | /* TODO: Add more CPU IDs after testing */ | ||
959 | {} | 980 | {} |
960 | }; | 981 | }; |
961 | MODULE_DEVICE_TABLE(x86cpu, rapl_ids); | 982 | MODULE_DEVICE_TABLE(x86cpu, rapl_ids); |
@@ -1358,14 +1379,18 @@ static struct notifier_block rapl_cpu_notifier = { | |||
1358 | static int __init rapl_init(void) | 1379 | static int __init rapl_init(void) |
1359 | { | 1380 | { |
1360 | int ret = 0; | 1381 | int ret = 0; |
1382 | const struct x86_cpu_id *id; | ||
1361 | 1383 | ||
1362 | if (!x86_match_cpu(rapl_ids)) { | 1384 | id = x86_match_cpu(rapl_ids); |
1385 | if (!id) { | ||
1363 | pr_err("driver does not support CPU family %d model %d\n", | 1386 | pr_err("driver does not support CPU family %d model %d\n", |
1364 | boot_cpu_data.x86, boot_cpu_data.x86_model); | 1387 | boot_cpu_data.x86, boot_cpu_data.x86_model); |
1365 | 1388 | ||
1366 | return -ENODEV; | 1389 | return -ENODEV; |
1367 | } | 1390 | } |
1368 | 1391 | ||
1392 | rapl_defaults = (struct rapl_defaults *)id->driver_data; | ||
1393 | |||
1369 | cpu_notifier_register_begin(); | 1394 | cpu_notifier_register_begin(); |
1370 | 1395 | ||
1371 | /* prevent CPU hotplug during detection */ | 1396 | /* prevent CPU hotplug during detection */ |