34
34
#include <asm/processor.h>
35
35
#include <asm/cpu_device_id.h>
36
36
37
+ /* Local defines */
38
+ #define MSR_PLATFORM_POWER_LIMIT 0x0000065C
39
+
37
40
/* bitmasks for RAPL MSRs, used by primitive access functions */
38
41
#define ENERGY_STATUS_MASK 0xffffffff
39
42
@@ -86,6 +89,7 @@ enum rapl_domain_type {
86
89
RAPL_DOMAIN_PP0 , /* core power plane */
87
90
RAPL_DOMAIN_PP1 , /* graphics uncore */
88
91
RAPL_DOMAIN_DRAM ,/* DRAM control_type */
92
+ RAPL_DOMAIN_PLATFORM , /* PSys control_type */
89
93
RAPL_DOMAIN_MAX ,
90
94
};
91
95
@@ -251,9 +255,11 @@ static const char * const rapl_domain_names[] = {
251
255
"core" ,
252
256
"uncore" ,
253
257
"dram" ,
258
+ "psys" ,
254
259
};
255
260
256
261
static struct powercap_control_type * control_type ; /* PowerCap Controller */
262
+ static struct rapl_domain * platform_rapl_domain ; /* Platform (PSys) domain */
257
263
258
264
/* caller to ensure CPU hotplug lock is held */
259
265
static struct rapl_package * find_package_by_id (int id )
@@ -409,6 +415,14 @@ static const struct powercap_zone_ops zone_ops[] = {
409
415
.set_enable = set_domain_enable ,
410
416
.get_enable = get_domain_enable ,
411
417
},
418
+ /* RAPL_DOMAIN_PLATFORM */
419
+ {
420
+ .get_energy_uj = get_energy_counter ,
421
+ .get_max_energy_range_uj = get_max_energy_counter ,
422
+ .release = release_zone ,
423
+ .set_enable = set_domain_enable ,
424
+ .get_enable = get_domain_enable ,
425
+ },
412
426
};
413
427
414
428
static int set_power_limit (struct powercap_zone * power_zone , int id ,
@@ -1160,6 +1174,13 @@ static int rapl_unregister_powercap(void)
1160
1174
powercap_unregister_zone (control_type ,
1161
1175
& rd_package -> power_zone );
1162
1176
}
1177
+
1178
+ if (platform_rapl_domain ) {
1179
+ powercap_unregister_zone (control_type ,
1180
+ & platform_rapl_domain -> power_zone );
1181
+ kfree (platform_rapl_domain );
1182
+ }
1183
+
1163
1184
powercap_unregister_control_type (control_type );
1164
1185
1165
1186
return 0 ;
@@ -1239,6 +1260,47 @@ static int rapl_package_register_powercap(struct rapl_package *rp)
1239
1260
return ret ;
1240
1261
}
1241
1262
1263
+ static int rapl_register_psys (void )
1264
+ {
1265
+ struct rapl_domain * rd ;
1266
+ struct powercap_zone * power_zone ;
1267
+ u64 val ;
1268
+
1269
+ if (rdmsrl_safe_on_cpu (0 , MSR_PLATFORM_ENERGY_STATUS , & val ) || !val )
1270
+ return - ENODEV ;
1271
+
1272
+ if (rdmsrl_safe_on_cpu (0 , MSR_PLATFORM_POWER_LIMIT , & val ) || !val )
1273
+ return - ENODEV ;
1274
+
1275
+ rd = kzalloc (sizeof (* rd ), GFP_KERNEL );
1276
+ if (!rd )
1277
+ return - ENOMEM ;
1278
+
1279
+ rd -> name = rapl_domain_names [RAPL_DOMAIN_PLATFORM ];
1280
+ rd -> id = RAPL_DOMAIN_PLATFORM ;
1281
+ rd -> msrs [0 ] = MSR_PLATFORM_POWER_LIMIT ;
1282
+ rd -> msrs [1 ] = MSR_PLATFORM_ENERGY_STATUS ;
1283
+ rd -> rpl [0 ].prim_id = PL1_ENABLE ;
1284
+ rd -> rpl [0 ].name = pl1_name ;
1285
+ rd -> rpl [1 ].prim_id = PL2_ENABLE ;
1286
+ rd -> rpl [1 ].name = pl2_name ;
1287
+ rd -> rp = find_package_by_id (0 );
1288
+
1289
+ power_zone = powercap_register_zone (& rd -> power_zone , control_type ,
1290
+ "psys" , NULL ,
1291
+ & zone_ops [RAPL_DOMAIN_PLATFORM ],
1292
+ 2 , & constraint_ops );
1293
+
1294
+ if (IS_ERR (power_zone )) {
1295
+ kfree (rd );
1296
+ return PTR_ERR (power_zone );
1297
+ }
1298
+
1299
+ platform_rapl_domain = rd ;
1300
+
1301
+ return 0 ;
1302
+ }
1303
+
1242
1304
static int rapl_register_powercap (void )
1243
1305
{
1244
1306
struct rapl_domain * rd ;
@@ -1255,6 +1317,10 @@ static int rapl_register_powercap(void)
1255
1317
list_for_each_entry (rp , & rapl_packages , plist )
1256
1318
if (rapl_package_register_powercap (rp ))
1257
1319
goto err_cleanup_package ;
1320
+
1321
+ /* Don't bail out if PSys is not supported */
1322
+ rapl_register_psys ();
1323
+
1258
1324
return ret ;
1259
1325
1260
1326
err_cleanup_package :
@@ -1289,6 +1355,9 @@ static int rapl_check_domain(int cpu, int domain)
1289
1355
case RAPL_DOMAIN_DRAM :
1290
1356
msr = MSR_DRAM_ENERGY_STATUS ;
1291
1357
break ;
1358
+ case RAPL_DOMAIN_PLATFORM :
1359
+ /* PSYS(PLATFORM) is not a CPU domain, so avoid printng error */
1360
+ return - EINVAL ;
1292
1361
default :
1293
1362
pr_err ("invalid domain id %d\n" , domain );
1294
1363
return - EINVAL ;
0 commit comments