Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

powercap: intel_rapl: Move MSR default settings into MSR interface driver

MSR-specific RAPL defaults differ from those used by the TPMI interface.
The MMIO and MSR interfaces shared the same rapl_defaults pointer in the
common driver, but MMIO does not require the CPU-specific variations
needed by MSR. Keeping these in the common driver adds unnecessary
complexity and MSR-specific initialization.

Move MSR defaults and CPU matching into the MSR interface driver.

Moves
-----
* Move rapl_check_unit_atom(), set_floor_freq_atom(), and
rapl_compute_time_window_atom() into intel_rapl_msr.c.
* Move MSR unit-field GENMASK definitions and local constants.
* Move all MSR-related rapl_defaults tables and the CPU-ID matching
logic (rapl_ids[]) into the MSR driver.
* Move iosf_mbi dependencies (floor-frequency control and related MBI
register definitions) as they are MSR-platform specific.

Modifications
-------------
* Replace the common driver's platform-device manual alloc/add sequence
with platform_device_register_data() in the MSR driver to pass
matching rapl_defaults as platform_data.
* Update MSR driver probe to assign pdev->dev.platform_data to
priv->defaults.
* Update Atom helper functions to use rp->lead_cpu directly for MSR
reads/writes instead of the generic get_rid().
* Update Atom floor frequency logic to access defaults via the
package private data pointer.
* Convert MSR device creation from fs_initcall() to module_init().
This preserves existing enumeration behavior as the driver was
already using module_init().
* Since rapl_ids need to exist after boot, remove __initconst
specifier.

No functional changes are expected.

Co-developed-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Signed-off-by: Kuppuswamy Sathyanarayanan <sathyanarayanan.kuppuswamy@linux.intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
Link: https://patch.msgid.link/20260331211950.3329932-2-sathyanarayanan.kuppuswamy@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>

authored by

Kuppuswamy Sathyanarayanan and committed by
Rafael J. Wysocki
e648c7ac 8765715b

+250 -228
+1 -227
drivers/powercap/intel_rapl_common.c
··· 28 28 29 29 #include <asm/cpu_device_id.h> 30 30 #include <asm/intel-family.h> 31 - #include <asm/iosf_mbi.h> 32 31 #include <asm/msr.h> 33 32 34 33 /* bitmasks for RAPL MSRs, used by primitive access functions */ ··· 210 211 211 212 #define power_zone_to_rapl_domain(_zone) \ 212 213 container_of(_zone, struct rapl_domain, power_zone) 213 - 214 - static const struct rapl_defaults *defaults_msr; 215 214 216 215 static const struct rapl_defaults *get_defaults(struct rapl_package *rp) 217 216 { ··· 756 759 /* MMIO I/F shares the same register layout as MSR registers */ 757 760 case RAPL_IF_MMIO: 758 761 case RAPL_IF_MSR: 759 - rp->priv->defaults = defaults_msr; 760 762 rp->priv->rpi = (void *)rpi_msr; 761 763 break; 762 764 case RAPL_IF_TPMI: ··· 943 947 } 944 948 EXPORT_SYMBOL_NS_GPL(rapl_default_check_unit, "INTEL_RAPL"); 945 949 946 - static int rapl_check_unit_atom(struct rapl_domain *rd) 947 - { 948 - struct reg_action ra; 949 - u32 value; 950 - 951 - ra.reg = rd->regs[RAPL_DOMAIN_REG_UNIT]; 952 - ra.mask = ~0; 953 - if (rd->rp->priv->read_raw(get_rid(rd->rp), &ra, false)) { 954 - pr_err("Failed to read power unit REG 0x%llx on %s:%s, exit.\n", 955 - ra.reg.val, rd->rp->name, rd->name); 956 - return -ENODEV; 957 - } 958 - 959 - value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; 960 - rd->energy_unit = ENERGY_UNIT_SCALE * (1ULL << value); 961 - 962 - value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; 963 - rd->power_unit = (1ULL << value) * MILLIWATT_PER_WATT; 964 - 965 - value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; 966 - rd->time_unit = USEC_PER_SEC >> value; 967 - 968 - pr_debug("Atom %s:%s energy=%dpJ, time=%dus, power=%duW\n", 969 - rd->rp->name, rd->name, rd->energy_unit, rd->time_unit, rd->power_unit); 970 - 971 - return 0; 972 - } 973 - 974 950 static void power_limit_irq_save_cpu(void *info) 975 951 { 976 952 u32 l, h = 0; ··· 1023 1055 } 1024 1056 EXPORT_SYMBOL_NS_GPL(rapl_default_set_floor_freq, "INTEL_RAPL"); 1025 1057 1026 - static void set_floor_freq_atom(struct rapl_domain *rd, bool enable) 1027 - { 1028 - static u32 power_ctrl_orig_val; 1029 - const struct rapl_defaults *defaults = get_defaults(rd->rp); 1030 - u32 mdata; 1031 - 1032 - if (!defaults->floor_freq_reg_addr) { 1033 - pr_err("Invalid floor frequency config register\n"); 1034 - return; 1035 - } 1036 - 1037 - if (!power_ctrl_orig_val) 1038 - iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_CR_READ, 1039 - defaults->floor_freq_reg_addr, 1040 - &power_ctrl_orig_val); 1041 - mdata = power_ctrl_orig_val; 1042 - if (enable) { 1043 - mdata &= ~GENMASK(14, 8); 1044 - mdata |= BIT(8); 1045 - } 1046 - iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_CR_WRITE, 1047 - defaults->floor_freq_reg_addr, mdata); 1048 - } 1049 - 1050 1058 u64 rapl_default_compute_time_window(struct rapl_domain *rd, u64 value, bool to_raw) 1051 1059 { 1052 1060 u64 f, y; /* fraction and exp. used for time unit */ ··· 1055 1111 return value; 1056 1112 } 1057 1113 EXPORT_SYMBOL_NS_GPL(rapl_default_compute_time_window, "INTEL_RAPL"); 1058 - 1059 - static u64 rapl_compute_time_window_atom(struct rapl_domain *rd, u64 value, 1060 - bool to_raw) 1061 - { 1062 - if (to_raw) 1063 - return div64_u64(value, rd->time_unit); 1064 - 1065 - /* 1066 - * Atom time unit encoding is straight forward val * time_unit, 1067 - * where time_unit is default to 1 sec. Never 0. 1068 - */ 1069 - return (value) ? value * rd->time_unit : rd->time_unit; 1070 - } 1071 - 1072 - static const struct rapl_defaults rapl_defaults_core = { 1073 - .floor_freq_reg_addr = 0, 1074 - .check_unit = rapl_default_check_unit, 1075 - .set_floor_freq = rapl_default_set_floor_freq, 1076 - .compute_time_window = rapl_default_compute_time_window, 1077 - }; 1078 - 1079 - static const struct rapl_defaults rapl_defaults_hsw_server = { 1080 - .check_unit = rapl_default_check_unit, 1081 - .set_floor_freq = rapl_default_set_floor_freq, 1082 - .compute_time_window = rapl_default_compute_time_window, 1083 - .dram_domain_energy_unit = 15300, 1084 - }; 1085 - 1086 - static const struct rapl_defaults rapl_defaults_spr_server = { 1087 - .check_unit = rapl_default_check_unit, 1088 - .set_floor_freq = rapl_default_set_floor_freq, 1089 - .compute_time_window = rapl_default_compute_time_window, 1090 - .psys_domain_energy_unit = NANOJOULE_PER_JOULE, 1091 - .spr_psys_bits = true, 1092 - }; 1093 - 1094 - static const struct rapl_defaults rapl_defaults_byt = { 1095 - .floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_BYT, 1096 - .check_unit = rapl_check_unit_atom, 1097 - .set_floor_freq = set_floor_freq_atom, 1098 - .compute_time_window = rapl_compute_time_window_atom, 1099 - }; 1100 - 1101 - static const struct rapl_defaults rapl_defaults_tng = { 1102 - .floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_TNG, 1103 - .check_unit = rapl_check_unit_atom, 1104 - .set_floor_freq = set_floor_freq_atom, 1105 - .compute_time_window = rapl_compute_time_window_atom, 1106 - }; 1107 - 1108 - static const struct rapl_defaults rapl_defaults_ann = { 1109 - .floor_freq_reg_addr = 0, 1110 - .check_unit = rapl_check_unit_atom, 1111 - .set_floor_freq = NULL, 1112 - .compute_time_window = rapl_compute_time_window_atom, 1113 - }; 1114 - 1115 - static const struct rapl_defaults rapl_defaults_cht = { 1116 - .floor_freq_reg_addr = 0, 1117 - .check_unit = rapl_check_unit_atom, 1118 - .set_floor_freq = NULL, 1119 - .compute_time_window = rapl_compute_time_window_atom, 1120 - }; 1121 - 1122 - static const struct rapl_defaults rapl_defaults_amd = { 1123 - .check_unit = rapl_default_check_unit, 1124 - }; 1125 - 1126 - static const struct x86_cpu_id rapl_ids[] __initconst = { 1127 - X86_MATCH_VFM(INTEL_SANDYBRIDGE, &rapl_defaults_core), 1128 - X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &rapl_defaults_core), 1129 - 1130 - X86_MATCH_VFM(INTEL_IVYBRIDGE, &rapl_defaults_core), 1131 - X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &rapl_defaults_core), 1132 - 1133 - X86_MATCH_VFM(INTEL_HASWELL, &rapl_defaults_core), 1134 - X86_MATCH_VFM(INTEL_HASWELL_L, &rapl_defaults_core), 1135 - X86_MATCH_VFM(INTEL_HASWELL_G, &rapl_defaults_core), 1136 - X86_MATCH_VFM(INTEL_HASWELL_X, &rapl_defaults_hsw_server), 1137 - 1138 - X86_MATCH_VFM(INTEL_BROADWELL, &rapl_defaults_core), 1139 - X86_MATCH_VFM(INTEL_BROADWELL_G, &rapl_defaults_core), 1140 - X86_MATCH_VFM(INTEL_BROADWELL_D, &rapl_defaults_core), 1141 - X86_MATCH_VFM(INTEL_BROADWELL_X, &rapl_defaults_hsw_server), 1142 - 1143 - X86_MATCH_VFM(INTEL_SKYLAKE, &rapl_defaults_core), 1144 - X86_MATCH_VFM(INTEL_SKYLAKE_L, &rapl_defaults_core), 1145 - X86_MATCH_VFM(INTEL_SKYLAKE_X, &rapl_defaults_hsw_server), 1146 - X86_MATCH_VFM(INTEL_KABYLAKE_L, &rapl_defaults_core), 1147 - X86_MATCH_VFM(INTEL_KABYLAKE, &rapl_defaults_core), 1148 - X86_MATCH_VFM(INTEL_CANNONLAKE_L, &rapl_defaults_core), 1149 - X86_MATCH_VFM(INTEL_ICELAKE_L, &rapl_defaults_core), 1150 - X86_MATCH_VFM(INTEL_ICELAKE, &rapl_defaults_core), 1151 - X86_MATCH_VFM(INTEL_ICELAKE_NNPI, &rapl_defaults_core), 1152 - X86_MATCH_VFM(INTEL_ICELAKE_X, &rapl_defaults_hsw_server), 1153 - X86_MATCH_VFM(INTEL_ICELAKE_D, &rapl_defaults_hsw_server), 1154 - X86_MATCH_VFM(INTEL_COMETLAKE_L, &rapl_defaults_core), 1155 - X86_MATCH_VFM(INTEL_COMETLAKE, &rapl_defaults_core), 1156 - X86_MATCH_VFM(INTEL_TIGERLAKE_L, &rapl_defaults_core), 1157 - X86_MATCH_VFM(INTEL_TIGERLAKE, &rapl_defaults_core), 1158 - X86_MATCH_VFM(INTEL_ROCKETLAKE, &rapl_defaults_core), 1159 - X86_MATCH_VFM(INTEL_ALDERLAKE, &rapl_defaults_core), 1160 - X86_MATCH_VFM(INTEL_ALDERLAKE_L, &rapl_defaults_core), 1161 - X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &rapl_defaults_core), 1162 - X86_MATCH_VFM(INTEL_RAPTORLAKE, &rapl_defaults_core), 1163 - X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &rapl_defaults_core), 1164 - X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &rapl_defaults_core), 1165 - X86_MATCH_VFM(INTEL_BARTLETTLAKE, &rapl_defaults_core), 1166 - X86_MATCH_VFM(INTEL_METEORLAKE, &rapl_defaults_core), 1167 - X86_MATCH_VFM(INTEL_METEORLAKE_L, &rapl_defaults_core), 1168 - X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &rapl_defaults_spr_server), 1169 - X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &rapl_defaults_spr_server), 1170 - X86_MATCH_VFM(INTEL_LUNARLAKE_M, &rapl_defaults_core), 1171 - X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &rapl_defaults_core), 1172 - X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &rapl_defaults_core), 1173 - X86_MATCH_VFM(INTEL_NOVALAKE, &rapl_defaults_core), 1174 - X86_MATCH_VFM(INTEL_NOVALAKE_L, &rapl_defaults_core), 1175 - X86_MATCH_VFM(INTEL_ARROWLAKE_H, &rapl_defaults_core), 1176 - X86_MATCH_VFM(INTEL_ARROWLAKE, &rapl_defaults_core), 1177 - X86_MATCH_VFM(INTEL_ARROWLAKE_U, &rapl_defaults_core), 1178 - X86_MATCH_VFM(INTEL_LAKEFIELD, &rapl_defaults_core), 1179 - 1180 - X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &rapl_defaults_byt), 1181 - X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &rapl_defaults_cht), 1182 - X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, &rapl_defaults_tng), 1183 - X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID2, &rapl_defaults_ann), 1184 - X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &rapl_defaults_core), 1185 - X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &rapl_defaults_core), 1186 - X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &rapl_defaults_core), 1187 - X86_MATCH_VFM(INTEL_ATOM_TREMONT, &rapl_defaults_core), 1188 - X86_MATCH_VFM(INTEL_ATOM_TREMONT_D, &rapl_defaults_core), 1189 - X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, &rapl_defaults_core), 1190 - 1191 - X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &rapl_defaults_hsw_server), 1192 - X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &rapl_defaults_hsw_server), 1193 - 1194 - X86_MATCH_VENDOR_FAM(AMD, 0x17, &rapl_defaults_amd), 1195 - X86_MATCH_VENDOR_FAM(AMD, 0x19, &rapl_defaults_amd), 1196 - X86_MATCH_VENDOR_FAM(AMD, 0x1A, &rapl_defaults_amd), 1197 - X86_MATCH_VENDOR_FAM(HYGON, 0x18, &rapl_defaults_amd), 1198 - {} 1199 - }; 1200 - MODULE_DEVICE_TABLE(x86cpu, rapl_ids); 1201 1114 1202 1115 /* Read once for all raw primitive data for domains */ 1203 1116 static void rapl_update_domain_data(struct rapl_package *rp) ··· 2067 2266 .notifier_call = rapl_pm_callback, 2068 2267 }; 2069 2268 2070 - static struct platform_device *rapl_msr_platdev; 2071 - 2072 2269 static int __init rapl_init(void) 2073 2270 { 2074 - const struct x86_cpu_id *id; 2075 - int ret; 2076 - 2077 - id = x86_match_cpu(rapl_ids); 2078 - if (id) { 2079 - defaults_msr = (const struct rapl_defaults *)id->driver_data; 2080 - 2081 - rapl_msr_platdev = platform_device_alloc("intel_rapl_msr", 0); 2082 - if (!rapl_msr_platdev) 2083 - return -ENOMEM; 2084 - 2085 - ret = platform_device_add(rapl_msr_platdev); 2086 - if (ret) { 2087 - platform_device_put(rapl_msr_platdev); 2088 - return ret; 2089 - } 2090 - } 2091 - 2092 - ret = register_pm_notifier(&rapl_pm_notifier); 2093 - if (ret && rapl_msr_platdev) { 2094 - platform_device_del(rapl_msr_platdev); 2095 - platform_device_put(rapl_msr_platdev); 2096 - } 2097 - 2098 - return ret; 2271 + return register_pm_notifier(&rapl_pm_notifier); 2099 2272 } 2100 2273 2101 2274 static void __exit rapl_exit(void) 2102 2275 { 2103 - platform_device_unregister(rapl_msr_platdev); 2104 2276 unregister_pm_notifier(&rapl_pm_notifier); 2105 2277 } 2106 2278
+249 -1
drivers/powercap/intel_rapl_msr.c
··· 21 21 #include <linux/intel_rapl.h> 22 22 #include <linux/processor.h> 23 23 #include <linux/platform_device.h> 24 + #include <linux/units.h> 25 + #include <linux/bits.h> 24 26 25 27 #include <asm/cpu_device_id.h> 26 28 #include <asm/intel-family.h> 29 + #include <asm/iosf_mbi.h> 27 30 #include <asm/msr.h> 28 31 29 32 /* Local defines */ 30 33 #define MSR_PLATFORM_POWER_LIMIT 0x0000065C 31 34 #define MSR_VR_CURRENT_CONFIG 0x00000601 35 + 36 + #define ENERGY_UNIT_SCALE 1000 /* scale from driver unit to powercap unit */ 37 + 38 + #define POWER_UNIT_OFFSET 0x00 39 + #define POWER_UNIT_MASK GENMASK(3, 0) 40 + 41 + #define ENERGY_UNIT_OFFSET 0x08 42 + #define ENERGY_UNIT_MASK GENMASK(12, 8) 43 + 44 + #define TIME_UNIT_OFFSET 0x10 45 + #define TIME_UNIT_MASK GENMASK(19, 16) 46 + 47 + /* Sideband MBI registers */ 48 + #define IOSF_CPU_POWER_BUDGET_CTL_BYT 0x02 49 + #define IOSF_CPU_POWER_BUDGET_CTL_TNG 0xDF 32 50 33 51 /* private data for RAPL MSR Interface */ 34 52 static struct rapl_if_priv *rapl_msr_priv; ··· 203 185 {} 204 186 }; 205 187 188 + static int rapl_check_unit_atom(struct rapl_domain *rd) 189 + { 190 + struct reg_action ra; 191 + u32 value; 192 + 193 + ra.reg = rd->regs[RAPL_DOMAIN_REG_UNIT]; 194 + ra.mask = ~0; 195 + if (rapl_msr_read_raw(rd->rp->lead_cpu, &ra, false)) { 196 + pr_err("Failed to read power unit REG 0x%llx on %s:%s, exit.\n", 197 + ra.reg.val, rd->rp->name, rd->name); 198 + return -ENODEV; 199 + } 200 + 201 + value = (ra.value & ENERGY_UNIT_MASK) >> ENERGY_UNIT_OFFSET; 202 + rd->energy_unit = ENERGY_UNIT_SCALE * (1ULL << value); 203 + 204 + value = (ra.value & POWER_UNIT_MASK) >> POWER_UNIT_OFFSET; 205 + rd->power_unit = (1ULL << value) * MILLIWATT_PER_WATT; 206 + 207 + value = (ra.value & TIME_UNIT_MASK) >> TIME_UNIT_OFFSET; 208 + rd->time_unit = USEC_PER_SEC >> value; 209 + 210 + pr_debug("Atom %s:%s energy=%dpJ, time=%dus, power=%duW\n", 211 + rd->rp->name, rd->name, rd->energy_unit, rd->time_unit, rd->power_unit); 212 + 213 + return 0; 214 + } 215 + 216 + static void set_floor_freq_atom(struct rapl_domain *rd, bool enable) 217 + { 218 + static u32 power_ctrl_orig_val; 219 + const struct rapl_defaults *defaults = rd->rp->priv->defaults; 220 + u32 mdata; 221 + 222 + if (!defaults->floor_freq_reg_addr) { 223 + pr_err("Invalid floor frequency config register\n"); 224 + return; 225 + } 226 + 227 + if (!power_ctrl_orig_val) 228 + iosf_mbi_read(BT_MBI_UNIT_PMC, MBI_CR_READ, 229 + defaults->floor_freq_reg_addr, 230 + &power_ctrl_orig_val); 231 + mdata = power_ctrl_orig_val; 232 + if (enable) { 233 + mdata &= ~GENMASK(14, 8); 234 + mdata |= BIT(8); 235 + } 236 + iosf_mbi_write(BT_MBI_UNIT_PMC, MBI_CR_WRITE, 237 + defaults->floor_freq_reg_addr, mdata); 238 + } 239 + 240 + static u64 rapl_compute_time_window_atom(struct rapl_domain *rd, u64 value, 241 + bool to_raw) 242 + { 243 + if (to_raw) 244 + return div64_u64(value, rd->time_unit); 245 + 246 + /* 247 + * Atom time unit encoding is straight forward val * time_unit, 248 + * where time_unit is default to 1 sec. Never 0. 249 + */ 250 + return value ? value * rd->time_unit : rd->time_unit; 251 + } 252 + 253 + static const struct rapl_defaults rapl_defaults_core = { 254 + .floor_freq_reg_addr = 0, 255 + .check_unit = rapl_default_check_unit, 256 + .set_floor_freq = rapl_default_set_floor_freq, 257 + .compute_time_window = rapl_default_compute_time_window, 258 + }; 259 + 260 + static const struct rapl_defaults rapl_defaults_hsw_server = { 261 + .check_unit = rapl_default_check_unit, 262 + .set_floor_freq = rapl_default_set_floor_freq, 263 + .compute_time_window = rapl_default_compute_time_window, 264 + .dram_domain_energy_unit = 15300, 265 + }; 266 + 267 + static const struct rapl_defaults rapl_defaults_spr_server = { 268 + .check_unit = rapl_default_check_unit, 269 + .set_floor_freq = rapl_default_set_floor_freq, 270 + .compute_time_window = rapl_default_compute_time_window, 271 + .psys_domain_energy_unit = NANOJOULE_PER_JOULE, 272 + .spr_psys_bits = true, 273 + }; 274 + 275 + static const struct rapl_defaults rapl_defaults_byt = { 276 + .floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_BYT, 277 + .check_unit = rapl_check_unit_atom, 278 + .set_floor_freq = set_floor_freq_atom, 279 + .compute_time_window = rapl_compute_time_window_atom, 280 + }; 281 + 282 + static const struct rapl_defaults rapl_defaults_tng = { 283 + .floor_freq_reg_addr = IOSF_CPU_POWER_BUDGET_CTL_TNG, 284 + .check_unit = rapl_check_unit_atom, 285 + .set_floor_freq = set_floor_freq_atom, 286 + .compute_time_window = rapl_compute_time_window_atom, 287 + }; 288 + 289 + static const struct rapl_defaults rapl_defaults_ann = { 290 + .floor_freq_reg_addr = 0, 291 + .check_unit = rapl_check_unit_atom, 292 + .set_floor_freq = NULL, 293 + .compute_time_window = rapl_compute_time_window_atom, 294 + }; 295 + 296 + static const struct rapl_defaults rapl_defaults_cht = { 297 + .floor_freq_reg_addr = 0, 298 + .check_unit = rapl_check_unit_atom, 299 + .set_floor_freq = NULL, 300 + .compute_time_window = rapl_compute_time_window_atom, 301 + }; 302 + 303 + static const struct rapl_defaults rapl_defaults_amd = { 304 + .check_unit = rapl_default_check_unit, 305 + }; 306 + 307 + static const struct x86_cpu_id rapl_ids[] = { 308 + X86_MATCH_VFM(INTEL_SANDYBRIDGE, &rapl_defaults_core), 309 + X86_MATCH_VFM(INTEL_SANDYBRIDGE_X, &rapl_defaults_core), 310 + 311 + X86_MATCH_VFM(INTEL_IVYBRIDGE, &rapl_defaults_core), 312 + X86_MATCH_VFM(INTEL_IVYBRIDGE_X, &rapl_defaults_core), 313 + 314 + X86_MATCH_VFM(INTEL_HASWELL, &rapl_defaults_core), 315 + X86_MATCH_VFM(INTEL_HASWELL_L, &rapl_defaults_core), 316 + X86_MATCH_VFM(INTEL_HASWELL_G, &rapl_defaults_core), 317 + X86_MATCH_VFM(INTEL_HASWELL_X, &rapl_defaults_hsw_server), 318 + 319 + X86_MATCH_VFM(INTEL_BROADWELL, &rapl_defaults_core), 320 + X86_MATCH_VFM(INTEL_BROADWELL_G, &rapl_defaults_core), 321 + X86_MATCH_VFM(INTEL_BROADWELL_D, &rapl_defaults_core), 322 + X86_MATCH_VFM(INTEL_BROADWELL_X, &rapl_defaults_hsw_server), 323 + 324 + X86_MATCH_VFM(INTEL_SKYLAKE, &rapl_defaults_core), 325 + X86_MATCH_VFM(INTEL_SKYLAKE_L, &rapl_defaults_core), 326 + X86_MATCH_VFM(INTEL_SKYLAKE_X, &rapl_defaults_hsw_server), 327 + X86_MATCH_VFM(INTEL_KABYLAKE_L, &rapl_defaults_core), 328 + X86_MATCH_VFM(INTEL_KABYLAKE, &rapl_defaults_core), 329 + X86_MATCH_VFM(INTEL_CANNONLAKE_L, &rapl_defaults_core), 330 + X86_MATCH_VFM(INTEL_ICELAKE_L, &rapl_defaults_core), 331 + X86_MATCH_VFM(INTEL_ICELAKE, &rapl_defaults_core), 332 + X86_MATCH_VFM(INTEL_ICELAKE_NNPI, &rapl_defaults_core), 333 + X86_MATCH_VFM(INTEL_ICELAKE_X, &rapl_defaults_hsw_server), 334 + X86_MATCH_VFM(INTEL_ICELAKE_D, &rapl_defaults_hsw_server), 335 + X86_MATCH_VFM(INTEL_COMETLAKE_L, &rapl_defaults_core), 336 + X86_MATCH_VFM(INTEL_COMETLAKE, &rapl_defaults_core), 337 + X86_MATCH_VFM(INTEL_TIGERLAKE_L, &rapl_defaults_core), 338 + X86_MATCH_VFM(INTEL_TIGERLAKE, &rapl_defaults_core), 339 + X86_MATCH_VFM(INTEL_ROCKETLAKE, &rapl_defaults_core), 340 + X86_MATCH_VFM(INTEL_ALDERLAKE, &rapl_defaults_core), 341 + X86_MATCH_VFM(INTEL_ALDERLAKE_L, &rapl_defaults_core), 342 + X86_MATCH_VFM(INTEL_ATOM_GRACEMONT, &rapl_defaults_core), 343 + X86_MATCH_VFM(INTEL_RAPTORLAKE, &rapl_defaults_core), 344 + X86_MATCH_VFM(INTEL_RAPTORLAKE_P, &rapl_defaults_core), 345 + X86_MATCH_VFM(INTEL_RAPTORLAKE_S, &rapl_defaults_core), 346 + X86_MATCH_VFM(INTEL_BARTLETTLAKE, &rapl_defaults_core), 347 + X86_MATCH_VFM(INTEL_METEORLAKE, &rapl_defaults_core), 348 + X86_MATCH_VFM(INTEL_METEORLAKE_L, &rapl_defaults_core), 349 + X86_MATCH_VFM(INTEL_SAPPHIRERAPIDS_X, &rapl_defaults_spr_server), 350 + X86_MATCH_VFM(INTEL_EMERALDRAPIDS_X, &rapl_defaults_spr_server), 351 + X86_MATCH_VFM(INTEL_LUNARLAKE_M, &rapl_defaults_core), 352 + X86_MATCH_VFM(INTEL_PANTHERLAKE_L, &rapl_defaults_core), 353 + X86_MATCH_VFM(INTEL_WILDCATLAKE_L, &rapl_defaults_core), 354 + X86_MATCH_VFM(INTEL_NOVALAKE, &rapl_defaults_core), 355 + X86_MATCH_VFM(INTEL_NOVALAKE_L, &rapl_defaults_core), 356 + X86_MATCH_VFM(INTEL_ARROWLAKE_H, &rapl_defaults_core), 357 + X86_MATCH_VFM(INTEL_ARROWLAKE, &rapl_defaults_core), 358 + X86_MATCH_VFM(INTEL_ARROWLAKE_U, &rapl_defaults_core), 359 + X86_MATCH_VFM(INTEL_LAKEFIELD, &rapl_defaults_core), 360 + 361 + X86_MATCH_VFM(INTEL_ATOM_SILVERMONT, &rapl_defaults_byt), 362 + X86_MATCH_VFM(INTEL_ATOM_AIRMONT, &rapl_defaults_cht), 363 + X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID, &rapl_defaults_tng), 364 + X86_MATCH_VFM(INTEL_ATOM_SILVERMONT_MID2, &rapl_defaults_ann), 365 + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT, &rapl_defaults_core), 366 + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_PLUS, &rapl_defaults_core), 367 + X86_MATCH_VFM(INTEL_ATOM_GOLDMONT_D, &rapl_defaults_core), 368 + X86_MATCH_VFM(INTEL_ATOM_TREMONT, &rapl_defaults_core), 369 + X86_MATCH_VFM(INTEL_ATOM_TREMONT_D, &rapl_defaults_core), 370 + X86_MATCH_VFM(INTEL_ATOM_TREMONT_L, &rapl_defaults_core), 371 + 372 + X86_MATCH_VFM(INTEL_XEON_PHI_KNL, &rapl_defaults_hsw_server), 373 + X86_MATCH_VFM(INTEL_XEON_PHI_KNM, &rapl_defaults_hsw_server), 374 + 375 + X86_MATCH_VENDOR_FAM(AMD, 0x17, &rapl_defaults_amd), 376 + X86_MATCH_VENDOR_FAM(AMD, 0x19, &rapl_defaults_amd), 377 + X86_MATCH_VENDOR_FAM(AMD, 0x1A, &rapl_defaults_amd), 378 + X86_MATCH_VENDOR_FAM(HYGON, 0x18, &rapl_defaults_amd), 379 + {} 380 + }; 381 + MODULE_DEVICE_TABLE(x86cpu, rapl_ids); 382 + 206 383 static int rapl_msr_probe(struct platform_device *pdev) 207 384 { 208 385 const struct x86_cpu_id *id = x86_match_cpu(pl4_support_ids); ··· 417 204 } 418 205 rapl_msr_priv->read_raw = rapl_msr_read_raw; 419 206 rapl_msr_priv->write_raw = rapl_msr_write_raw; 207 + rapl_msr_priv->defaults = (const struct rapl_defaults *)pdev->dev.platform_data; 420 208 421 209 if (id) { 422 210 rapl_msr_priv->limits[RAPL_DOMAIN_PACKAGE] |= BIT(POWER_LIMIT4); ··· 472 258 }, 473 259 }; 474 260 475 - module_platform_driver(intel_rapl_msr_driver); 261 + static struct platform_device *rapl_msr_platdev; 262 + 263 + static int intel_rapl_msr_init(void) 264 + { 265 + const struct rapl_defaults *def; 266 + const struct x86_cpu_id *id; 267 + int ret; 268 + 269 + ret = platform_driver_register(&intel_rapl_msr_driver); 270 + if (ret) 271 + return ret; 272 + 273 + /* Create the MSR RAPL platform device for supported platforms */ 274 + id = x86_match_cpu(rapl_ids); 275 + if (!id) 276 + return 0; 277 + 278 + def = (const struct rapl_defaults *)id->driver_data; 279 + 280 + rapl_msr_platdev = platform_device_register_data(NULL, "intel_rapl_msr", 0, def, 281 + sizeof(*def)); 282 + if (IS_ERR(rapl_msr_platdev)) 283 + pr_debug("intel_rapl_msr device register failed, ret:%ld\n", 284 + PTR_ERR(rapl_msr_platdev)); 285 + 286 + return 0; 287 + } 288 + module_init(intel_rapl_msr_init); 289 + 290 + static void intel_rapl_msr_exit(void) 291 + { 292 + platform_device_unregister(rapl_msr_platdev); 293 + platform_driver_unregister(&intel_rapl_msr_driver); 294 + } 295 + module_exit(intel_rapl_msr_exit); 476 296 477 297 MODULE_DESCRIPTION("Driver for Intel RAPL (Running Average Power Limit) control via MSR interface"); 478 298 MODULE_AUTHOR("Zhang Rui <rui.zhang@intel.com>");