@@ -105,9 +105,9 @@ static const char pl4_name[] = "peak_power";
105105
106106struct rapl_defaults {
107107 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 );
109109 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 ,
111111 bool to_raw );
112112 unsigned int dram_domain_energy_unit ;
113113 unsigned int psys_domain_energy_unit ;
@@ -557,7 +557,6 @@ static void rapl_init_domains(struct rapl_package *rp)
557557 enum rapl_domain_type i ;
558558 enum rapl_domain_reg_id j ;
559559 struct rapl_domain * rd = rp -> domains ;
560- struct rapl_defaults * defaults = get_defaults (rp );
561560
562561 for (i = 0 ; i < RAPL_DOMAIN_MAX ; i ++ ) {
563562 unsigned int mask = rp -> domain_map & (1 << i );
@@ -596,24 +595,6 @@ static void rapl_init_domains(struct rapl_package *rp)
596595 for (j = 0 ; j < RAPL_DOMAIN_REG_MAX ; j ++ )
597596 rd -> regs [j ] = rp -> priv -> regs [i ][j ];
598597
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- }
617598 rd ++ ;
618599 }
619600}
@@ -622,24 +603,19 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
622603 u64 value , int to_raw )
623604{
624605 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 );
627607 u64 scale = 1 ;
628608
629609 switch (type ) {
630610 case POWER_UNIT :
631- units = rp -> power_unit ;
611+ units = rd -> power_unit ;
632612 break ;
633613 case ENERGY_UNIT :
634614 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 ;
640616 break ;
641617 case TIME_UNIT :
642- return defaults -> compute_time_window (rp , value , to_raw );
618+ return defaults -> compute_time_window (rd , value , to_raw );
643619 case ARBITRARY_UNIT :
644620 default :
645621 return value ;
@@ -857,58 +833,58 @@ static int rapl_write_data_raw(struct rapl_domain *rd,
857833 * power unit : microWatts : Represented in milliWatts by default
858834 * time unit : microseconds: Represented in seconds by default
859835 */
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 )
861837{
862838 struct reg_action ra ;
863839 u32 value ;
864840
865- ra .reg = rp -> priv -> reg_unit ;
841+ ra .reg = rd -> regs [ RAPL_DOMAIN_REG_UNIT ] ;
866842 ra .mask = ~0 ;
867- if (rp -> priv -> read_raw (cpu , & ra )) {
843+ if (rd -> rp -> priv -> read_raw (cpu , & ra )) {
868844 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 );
870846 return - ENODEV ;
871847 }
872848
873849 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 );
875851
876852 value = (ra .value & POWER_UNIT_MASK ) >> POWER_UNIT_OFFSET ;
877- rp -> power_unit = 1000000 / (1 << value );
853+ rd -> power_unit = 1000000 / (1 << value );
878854
879855 value = (ra .value & TIME_UNIT_MASK ) >> TIME_UNIT_OFFSET ;
880- rp -> time_unit = 1000000 / (1 << value );
856+ rd -> time_unit = 1000000 / (1 << value );
881857
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 );
884860
885861 return 0 ;
886862}
887863
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 )
889865{
890866 struct reg_action ra ;
891867 u32 value ;
892868
893- ra .reg = rp -> priv -> reg_unit ;
869+ ra .reg = rd -> regs [ RAPL_DOMAIN_REG_UNIT ] ;
894870 ra .mask = ~0 ;
895- if (rp -> priv -> read_raw (cpu , & ra )) {
871+ if (rd -> rp -> priv -> read_raw (cpu , & ra )) {
896872 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 );
898874 return - ENODEV ;
899875 }
900876
901877 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 ;
903879
904880 value = (ra .value & POWER_UNIT_MASK ) >> POWER_UNIT_OFFSET ;
905- rp -> power_unit = (1 << value ) * 1000 ;
881+ rd -> power_unit = (1 << value ) * 1000 ;
906882
907883 value = (ra .value & TIME_UNIT_MASK ) >> TIME_UNIT_OFFSET ;
908- rp -> time_unit = 1000000 / (1 << value );
884+ rd -> time_unit = 1000000 / (1 << value );
909885
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 );
912888
913889 return 0 ;
914890}
@@ -1011,7 +987,7 @@ static void set_floor_freq_atom(struct rapl_domain *rd, bool enable)
1011987 defaults -> floor_freq_reg_addr , mdata );
1012988}
1013989
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 ,
1015991 bool to_raw )
1016992{
1017993 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,
1023999 if (!to_raw ) {
10241000 f = (value & 0x60 ) >> 5 ;
10251001 y = value & 0x1f ;
1026- value = (1 << y ) * (4 + f ) * rp -> time_unit / 4 ;
1002+ value = (1 << y ) * (4 + f ) * rd -> time_unit / 4 ;
10271003 } else {
1028- if (value < rp -> time_unit )
1004+ if (value < rd -> time_unit )
10291005 return 0 ;
10301006
1031- do_div (value , rp -> time_unit );
1007+ do_div (value , rd -> time_unit );
10321008 y = ilog2 (value );
10331009
10341010 /*
@@ -1044,17 +1020,17 @@ static u64 rapl_compute_time_window_core(struct rapl_package *rp, u64 value,
10441020 return value ;
10451021}
10461022
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 ,
10481024 bool to_raw )
10491025{
10501026 /*
10511027 * Atom time unit encoding is straight forward val * time_unit,
10521028 * where time_unit is default to 1 sec. Never 0.
10531029 */
10541030 if (!to_raw )
1055- return (value ) ? value * rp -> time_unit : rp -> time_unit ;
1031+ return (value ) ? value * rd -> time_unit : rd -> time_unit ;
10561032
1057- value = div64_u64 (value , rp -> time_unit );
1033+ value = div64_u64 (value , rd -> time_unit );
10581034
10591035 return value ;
10601036}
@@ -1299,6 +1275,40 @@ static int rapl_check_domain(int cpu, int domain, struct rapl_package *rp)
12991275 return 0 ;
13001276}
13011277
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+
13021312/*
13031313 * Check if power limits are available. Two cases when they are not available:
13041314 * 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)
13591369
13601370 rapl_init_domains (rp );
13611371
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 );
13631374 rapl_detect_powerlimit (rd );
1375+ }
13641376
13651377 return 0 ;
13661378}
@@ -1418,7 +1430,6 @@ struct rapl_package *rapl_add_package(int cpu, struct rapl_if_priv *priv)
14181430{
14191431 int id = topology_logical_die_id (cpu );
14201432 struct rapl_package * rp ;
1421- struct rapl_defaults * defaults ;
14221433 int ret ;
14231434
14241435 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)
14421453 snprintf (rp -> name , PACKAGE_DOMAIN_NAME_LENGTH , "package-%d" ,
14431454 topology_physical_package_id (cpu ));
14441455
1445- defaults = get_defaults (rp );
14461456 /* 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 )) {
14481458 ret = - ENODEV ;
14491459 goto err_free_package ;
14501460 }
0 commit comments