@@ -105,9 +105,9 @@ static const char pl4_name[] = "peak_power";
105
105
106
106
struct rapl_defaults {
107
107
u8 floor_freq_reg_addr ;
108
- int (* check_unit )(struct rapl_package * rp , int cpu );
108
+ int (* check_unit )(struct rapl_domain * rd , int cpu );
109
109
void (* set_floor_freq )(struct rapl_domain * rd , bool mode );
110
- u64 (* compute_time_window )(struct rapl_package * rp , u64 val ,
110
+ u64 (* compute_time_window )(struct rapl_domain * rd , u64 val ,
111
111
bool to_raw );
112
112
unsigned int dram_domain_energy_unit ;
113
113
unsigned int psys_domain_energy_unit ;
@@ -557,7 +557,6 @@ static void rapl_init_domains(struct rapl_package *rp)
557
557
enum rapl_domain_type i ;
558
558
enum rapl_domain_reg_id j ;
559
559
struct rapl_domain * rd = rp -> domains ;
560
- struct rapl_defaults * defaults = get_defaults (rp );
561
560
562
561
for (i = 0 ; i < RAPL_DOMAIN_MAX ; i ++ ) {
563
562
unsigned int mask = rp -> domain_map & (1 << i );
@@ -596,24 +595,6 @@ static void rapl_init_domains(struct rapl_package *rp)
596
595
for (j = 0 ; j < RAPL_DOMAIN_REG_MAX ; j ++ )
597
596
rd -> regs [j ] = rp -> priv -> regs [i ][j ];
598
597
599
- switch (i ) {
600
- case RAPL_DOMAIN_DRAM :
601
- rd -> domain_energy_unit =
602
- defaults -> dram_domain_energy_unit ;
603
- if (rd -> domain_energy_unit )
604
- pr_info ("DRAM domain energy unit %dpj\n" ,
605
- rd -> domain_energy_unit );
606
- break ;
607
- case RAPL_DOMAIN_PLATFORM :
608
- rd -> domain_energy_unit =
609
- defaults -> psys_domain_energy_unit ;
610
- if (rd -> domain_energy_unit )
611
- pr_info ("Platform domain energy unit %dpj\n" ,
612
- rd -> domain_energy_unit );
613
- break ;
614
- default :
615
- break ;
616
- }
617
598
rd ++ ;
618
599
}
619
600
}
@@ -622,24 +603,19 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
622
603
u64 value , int to_raw )
623
604
{
624
605
u64 units = 1 ;
625
- struct rapl_package * rp = rd -> rp ;
626
- struct rapl_defaults * defaults = get_defaults (rp );
606
+ struct rapl_defaults * defaults = get_defaults (rd -> rp );
627
607
u64 scale = 1 ;
628
608
629
609
switch (type ) {
630
610
case POWER_UNIT :
631
- units = rp -> power_unit ;
611
+ units = rd -> power_unit ;
632
612
break ;
633
613
case ENERGY_UNIT :
634
614
scale = ENERGY_UNIT_SCALE ;
635
- /* per domain unit takes precedence */
636
- if (rd -> domain_energy_unit )
637
- units = rd -> domain_energy_unit ;
638
- else
639
- units = rp -> energy_unit ;
615
+ units = rd -> energy_unit ;
640
616
break ;
641
617
case TIME_UNIT :
642
- return defaults -> compute_time_window (rp , value , to_raw );
618
+ return defaults -> compute_time_window (rd , value , to_raw );
643
619
case ARBITRARY_UNIT :
644
620
default :
645
621
return value ;
@@ -857,58 +833,58 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
857
833
* power unit : microWatts : Represented in milliWatts by default
858
834
* time unit : microseconds: Represented in seconds by default
859
835
*/
860
- static int rapl_check_unit_core (struct rapl_package * rp , int cpu )
836
+ static int rapl_check_unit_core (struct rapl_domain * rd , int cpu )
861
837
{
862
838
struct reg_action ra ;
863
839
u32 value ;
864
840
865
- ra .reg = rp -> priv -> reg_unit ;
841
+ ra .reg = rd -> regs [ RAPL_DOMAIN_REG_UNIT ] ;
866
842
ra .mask = ~0 ;
867
- if (rp -> priv -> read_raw (cpu , & ra )) {
843
+ if (rd -> rp -> priv -> read_raw (cpu , & ra )) {
868
844
pr_err ("Failed to read power unit REG 0x%llx on CPU %d, exit.\n" ,
869
- rp -> priv -> reg_unit , cpu );
845
+ ra . reg , cpu );
870
846
return - ENODEV ;
871
847
}
872
848
873
849
value = (ra .value & ENERGY_UNIT_MASK ) >> ENERGY_UNIT_OFFSET ;
874
- rp -> energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value );
850
+ rd -> energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value );
875
851
876
852
value = (ra .value & POWER_UNIT_MASK ) >> POWER_UNIT_OFFSET ;
877
- rp -> power_unit = 1000000 / (1 << value );
853
+ rd -> power_unit = 1000000 / (1 << value );
878
854
879
855
value = (ra .value & TIME_UNIT_MASK ) >> TIME_UNIT_OFFSET ;
880
- rp -> time_unit = 1000000 / (1 << value );
856
+ rd -> time_unit = 1000000 / (1 << value );
881
857
882
- pr_debug ("Core CPU %s energy=%dpJ, time=%dus, power=%duW\n" ,
883
- rp -> name , rp -> energy_unit , rp -> time_unit , rp -> power_unit );
858
+ pr_debug ("Core CPU %s:%s energy=%dpJ, time=%dus, power=%duW\n" ,
859
+ rd -> rp -> name , rd -> name , rd -> energy_unit , rd -> time_unit , rd -> power_unit );
884
860
885
861
return 0 ;
886
862
}
887
863
888
- static int rapl_check_unit_atom (struct rapl_package * rp , int cpu )
864
+ static int rapl_check_unit_atom (struct rapl_domain * rd , int cpu )
889
865
{
890
866
struct reg_action ra ;
891
867
u32 value ;
892
868
893
- ra .reg = rp -> priv -> reg_unit ;
869
+ ra .reg = rd -> regs [ RAPL_DOMAIN_REG_UNIT ] ;
894
870
ra .mask = ~0 ;
895
- if (rp -> priv -> read_raw (cpu , & ra )) {
871
+ if (rd -> rp -> priv -> read_raw (cpu , & ra )) {
896
872
pr_err ("Failed to read power unit REG 0x%llx on CPU %d, exit.\n" ,
897
- rp -> priv -> reg_unit , cpu );
873
+ ra . reg , cpu );
898
874
return - ENODEV ;
899
875
}
900
876
901
877
value = (ra .value & ENERGY_UNIT_MASK ) >> ENERGY_UNIT_OFFSET ;
902
- rp -> energy_unit = ENERGY_UNIT_SCALE * 1 << value ;
878
+ rd -> energy_unit = ENERGY_UNIT_SCALE * 1 << value ;
903
879
904
880
value = (ra .value & POWER_UNIT_MASK ) >> POWER_UNIT_OFFSET ;
905
- rp -> power_unit = (1 << value ) * 1000 ;
881
+ rd -> power_unit = (1 << value ) * 1000 ;
906
882
907
883
value = (ra .value & TIME_UNIT_MASK ) >> TIME_UNIT_OFFSET ;
908
- rp -> time_unit = 1000000 / (1 << value );
884
+ rd -> time_unit = 1000000 / (1 << value );
909
885
910
- pr_debug ("Atom %s energy=%dpJ, time=%dus, power=%duW\n" ,
911
- rp -> name , rp -> energy_unit , rp -> time_unit , rp -> power_unit );
886
+ pr_debug ("Atom %s:%s energy=%dpJ, time=%dus, power=%duW\n" ,
887
+ rd -> rp -> name , rd -> name , rd -> energy_unit , rd -> time_unit , rd -> power_unit );
912
888
913
889
return 0 ;
914
890
}
@@ -1011,7 +987,7 @@ static void set_floor_freq_atom(struct rapl_domain *rd, bool enable)
1011
987
defaults -> floor_freq_reg_addr , mdata );
1012
988
}
1013
989
1014
- static u64 rapl_compute_time_window_core (struct rapl_package * rp , u64 value ,
990
+ static u64 rapl_compute_time_window_core (struct rapl_domain * rd , u64 value ,
1015
991
bool to_raw )
1016
992
{
1017
993
u64 f , y ; /* fraction and exp. used for time unit */
@@ -1023,12 +999,12 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value,
1023
999
if (!to_raw ) {
1024
1000
f = (value & 0x60 ) >> 5 ;
1025
1001
y = value & 0x1f ;
1026
- value = (1 << y ) * (4 + f ) * rp -> time_unit / 4 ;
1002
+ value = (1 << y ) * (4 + f ) * rd -> time_unit / 4 ;
1027
1003
} else {
1028
- if (value < rp -> time_unit )
1004
+ if (value < rd -> time_unit )
1029
1005
return 0 ;
1030
1006
1031
- do_div (value , rp -> time_unit );
1007
+ do_div (value , rd -> time_unit );
1032
1008
y = ilog2 (value );
1033
1009
1034
1010
/*
@@ -1044,17 +1020,17 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value,
1044
1020
return value ;
1045
1021
}
1046
1022
1047
- static u64 rapl_compute_time_window_atom (struct rapl_package * rp , u64 value ,
1023
+ static u64 rapl_compute_time_window_atom (struct rapl_domain * rd , u64 value ,
1048
1024
bool to_raw )
1049
1025
{
1050
1026
/*
1051
1027
* Atom time unit encoding is straight forward val * time_unit,
1052
1028
* where time_unit is default to 1 sec. Never 0.
1053
1029
*/
1054
1030
if (!to_raw )
1055
- return (value ) ? value * rp -> time_unit : rp -> time_unit ;
1031
+ return (value ) ? value * rd -> time_unit : rd -> time_unit ;
1056
1032
1057
- value = div64_u64 (value , rp -> time_unit );
1033
+ value = div64_u64 (value , rd -> time_unit );
1058
1034
1059
1035
return value ;
1060
1036
}
@@ -1299,6 +1275,40 @@ static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
1299
1275
return 0 ;
1300
1276
}
1301
1277
1278
+ /*
1279
+ * Get per domain energy/power/time unit.
1280
+ * RAPL Interfaces without per domain unit register will use the package
1281
+ * scope unit register to set per domain units.
1282
+ */
1283
+ static int rapl_get_domain_unit (struct rapl_domain * rd )
1284
+ {
1285
+ struct rapl_defaults * defaults = get_defaults (rd -> rp );
1286
+ int ret ;
1287
+
1288
+ if (!rd -> regs [RAPL_DOMAIN_REG_UNIT ]) {
1289
+ if (!rd -> rp -> priv -> reg_unit ) {
1290
+ pr_err ("No valid Unit register found\n" );
1291
+ return - ENODEV ;
1292
+ }
1293
+ rd -> regs [RAPL_DOMAIN_REG_UNIT ] = rd -> rp -> priv -> reg_unit ;
1294
+ }
1295
+
1296
+ if (!defaults -> check_unit ) {
1297
+ pr_err ("missing .check_unit() callback\n" );
1298
+ return - ENODEV ;
1299
+ }
1300
+
1301
+ ret = defaults -> check_unit (rd , rd -> rp -> lead_cpu );
1302
+ if (ret )
1303
+ return ret ;
1304
+
1305
+ if (rd -> id == RAPL_DOMAIN_DRAM && defaults -> dram_domain_energy_unit )
1306
+ rd -> energy_unit = defaults -> dram_domain_energy_unit ;
1307
+ if (rd -> id == RAPL_DOMAIN_PLATFORM && defaults -> psys_domain_energy_unit )
1308
+ rd -> energy_unit = defaults -> psys_domain_energy_unit ;
1309
+ return 0 ;
1310
+ }
1311
+
1302
1312
/*
1303
1313
* Check if power limits are available. Two cases when they are not available:
1304
1314
* 1. Locked by BIOS, in this case we still provide read-only access so that
@@ -1359,8 +1369,10 @@ static int rapl_detect_domains(struct rapl_package *rp, int cpu)
1359
1369
1360
1370
rapl_init_domains (rp );
1361
1371
1362
- for (rd = rp -> domains ; rd < rp -> domains + rp -> nr_domains ; rd ++ )
1372
+ for (rd = rp -> domains ; rd < rp -> domains + rp -> nr_domains ; rd ++ ) {
1373
+ rapl_get_domain_unit (rd );
1363
1374
rapl_detect_powerlimit (rd );
1375
+ }
1364
1376
1365
1377
return 0 ;
1366
1378
}
@@ -1418,7 +1430,6 @@ struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
1418
1430
{
1419
1431
int id = topology_logical_die_id (cpu );
1420
1432
struct rapl_package * rp ;
1421
- struct rapl_defaults * defaults ;
1422
1433
int ret ;
1423
1434
1424
1435
rp = kzalloc (sizeof (struct rapl_package ), GFP_KERNEL );
@@ -1442,9 +1453,8 @@ struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
1442
1453
snprintf (rp -> name , PACKAGE_DOMAIN_NAME_LENGTH , "package-%d" ,
1443
1454
topology_physical_package_id (cpu ));
1444
1455
1445
- defaults = get_defaults (rp );
1446
1456
/* check if the package contains valid domains */
1447
- if (rapl_detect_domains (rp , cpu ) || defaults -> check_unit ( rp , cpu ) ) {
1457
+ if (rapl_detect_domains (rp , cpu )) {
1448
1458
ret = - ENODEV ;
1449
1459
goto err_free_package ;
1450
1460
}
0 commit comments