7575#define PSYS_TIME_WINDOW1_MASK (0x7FULL<<19)
7676#define PSYS_TIME_WINDOW2_MASK (0x7FULL<<51)
7777
78+ /* bitmasks for RAPL TPMI, used by primitive access functions */
79+ #define TPMI_POWER_LIMIT_MASK 0x3FFFF
80+ #define TPMI_POWER_LIMIT_ENABLE BIT_ULL(62)
81+ #define TPMI_TIME_WINDOW_MASK (0x7FULL<<18)
82+ #define TPMI_INFO_SPEC_MASK 0x3FFFF
83+ #define TPMI_INFO_MIN_MASK (0x3FFFFULL << 18)
84+ #define TPMI_INFO_MAX_MASK (0x3FFFFULL << 36)
85+ #define TPMI_INFO_MAX_TIME_WIN_MASK (0x7FULL << 54)
86+
7887/* Non HW constants */
7988#define RAPL_PRIMITIVE_DERIVED BIT(1) /* not from raw data */
8089#define RAPL_PRIMITIVE_DUMMY BIT(2)
@@ -119,6 +128,19 @@ static bool is_pl_valid(struct rapl_domain *rd, int pl)
119128
120129static int get_pl_lock_prim (struct rapl_domain * rd , int pl )
121130{
131+ if (rd -> rp -> priv -> type == RAPL_IF_TPMI ) {
132+ if (pl == POWER_LIMIT1 )
133+ return PL1_LOCK ;
134+ if (pl == POWER_LIMIT2 )
135+ return PL2_LOCK ;
136+ if (pl == POWER_LIMIT4 )
137+ return PL4_LOCK ;
138+ }
139+
140+ /* MSR/MMIO Interface doesn't have Lock bit for PL4 */
141+ if (pl == POWER_LIMIT4 )
142+ return - EINVAL ;
143+
122144 /*
123145 * Power Limit register that supports two power limits has a different
124146 * bit position for the Lock bit.
@@ -134,7 +156,7 @@ static int get_pl_prim(struct rapl_domain *rd, int pl, enum pl_prims prim)
134156 case POWER_LIMIT1 :
135157 if (prim == PL_ENABLE )
136158 return PL1_ENABLE ;
137- if (prim == PL_CLAMP )
159+ if (prim == PL_CLAMP && rd -> rp -> priv -> type != RAPL_IF_TPMI )
138160 return PL1_CLAMP ;
139161 if (prim == PL_LIMIT )
140162 return POWER_LIMIT1 ;
@@ -148,7 +170,7 @@ static int get_pl_prim(struct rapl_domain *rd, int pl, enum pl_prims prim)
148170 case POWER_LIMIT2 :
149171 if (prim == PL_ENABLE )
150172 return PL2_ENABLE ;
151- if (prim == PL_CLAMP )
173+ if (prim == PL_CLAMP && rd -> rp -> priv -> type != RAPL_IF_TPMI )
152174 return PL2_CLAMP ;
153175 if (prim == PL_LIMIT )
154176 return POWER_LIMIT2 ;
@@ -167,6 +189,8 @@ static int get_pl_prim(struct rapl_domain *rd, int pl, enum pl_prims prim)
167189 /* PL4 would be around two times PL2, use same prim as PL2. */
168190 if (prim == PL_MAX_POWER )
169191 return MAX_POWER ;
192+ if (prim == PL_LOCK )
193+ return get_pl_lock_prim (rd , pl );
170194 return - EINVAL ;
171195 default :
172196 return - EINVAL ;
@@ -187,6 +211,7 @@ struct rapl_defaults {
187211 bool spr_psys_bits ;
188212};
189213static struct rapl_defaults * defaults_msr ;
214+ static const struct rapl_defaults defaults_tpmi ;
190215
191216static struct rapl_defaults * get_defaults (struct rapl_package * rp )
192217{
@@ -610,6 +635,7 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
610635 return div64_u64 (value , scale );
611636}
612637
638+ /* RAPL primitives for MSR and MMIO I/F */
613639static struct rapl_primitive_info rpi_msr [NR_RAPL_PRIMITIVES ] = {
614640 /* name, mask, shift, msr index, unit divisor */
615641 [POWER_LIMIT1 ] = PRIMITIVE_INFO_INIT (POWER_LIMIT1 , POWER_LIMIT1_MASK , 0 ,
@@ -667,6 +693,48 @@ static struct rapl_primitive_info rpi_msr[NR_RAPL_PRIMITIVES] = {
667693 RAPL_PRIMITIVE_DERIVED ),
668694};
669695
696+ /* RAPL primitives for TPMI I/F */
697+ static struct rapl_primitive_info rpi_tpmi [NR_RAPL_PRIMITIVES ] = {
698+ /* name, mask, shift, msr index, unit divisor */
699+ [POWER_LIMIT1 ] = PRIMITIVE_INFO_INIT (POWER_LIMIT1 , TPMI_POWER_LIMIT_MASK , 0 ,
700+ RAPL_DOMAIN_REG_LIMIT , POWER_UNIT , 0 ),
701+ [POWER_LIMIT2 ] = PRIMITIVE_INFO_INIT (POWER_LIMIT2 , TPMI_POWER_LIMIT_MASK , 0 ,
702+ RAPL_DOMAIN_REG_PL2 , POWER_UNIT , 0 ),
703+ [POWER_LIMIT4 ] = PRIMITIVE_INFO_INIT (POWER_LIMIT4 , TPMI_POWER_LIMIT_MASK , 0 ,
704+ RAPL_DOMAIN_REG_PL4 , POWER_UNIT , 0 ),
705+ [ENERGY_COUNTER ] = PRIMITIVE_INFO_INIT (ENERGY_COUNTER , ENERGY_STATUS_MASK , 0 ,
706+ RAPL_DOMAIN_REG_STATUS , ENERGY_UNIT , 0 ),
707+ [PL1_LOCK ] = PRIMITIVE_INFO_INIT (PL1_LOCK , POWER_HIGH_LOCK , 63 ,
708+ RAPL_DOMAIN_REG_LIMIT , ARBITRARY_UNIT , 0 ),
709+ [PL2_LOCK ] = PRIMITIVE_INFO_INIT (PL2_LOCK , POWER_HIGH_LOCK , 63 ,
710+ RAPL_DOMAIN_REG_PL2 , ARBITRARY_UNIT , 0 ),
711+ [PL4_LOCK ] = PRIMITIVE_INFO_INIT (PL4_LOCK , POWER_HIGH_LOCK , 63 ,
712+ RAPL_DOMAIN_REG_PL4 , ARBITRARY_UNIT , 0 ),
713+ [PL1_ENABLE ] = PRIMITIVE_INFO_INIT (PL1_ENABLE , TPMI_POWER_LIMIT_ENABLE , 62 ,
714+ RAPL_DOMAIN_REG_LIMIT , ARBITRARY_UNIT , 0 ),
715+ [PL2_ENABLE ] = PRIMITIVE_INFO_INIT (PL2_ENABLE , TPMI_POWER_LIMIT_ENABLE , 62 ,
716+ RAPL_DOMAIN_REG_PL2 , ARBITRARY_UNIT , 0 ),
717+ [PL4_ENABLE ] = PRIMITIVE_INFO_INIT (PL4_ENABLE , TPMI_POWER_LIMIT_ENABLE , 62 ,
718+ RAPL_DOMAIN_REG_PL4 , ARBITRARY_UNIT , 0 ),
719+ [TIME_WINDOW1 ] = PRIMITIVE_INFO_INIT (TIME_WINDOW1 , TPMI_TIME_WINDOW_MASK , 18 ,
720+ RAPL_DOMAIN_REG_LIMIT , TIME_UNIT , 0 ),
721+ [TIME_WINDOW2 ] = PRIMITIVE_INFO_INIT (TIME_WINDOW2 , TPMI_TIME_WINDOW_MASK , 18 ,
722+ RAPL_DOMAIN_REG_PL2 , TIME_UNIT , 0 ),
723+ [THERMAL_SPEC_POWER ] = PRIMITIVE_INFO_INIT (THERMAL_SPEC_POWER , TPMI_INFO_SPEC_MASK , 0 ,
724+ RAPL_DOMAIN_REG_INFO , POWER_UNIT , 0 ),
725+ [MAX_POWER ] = PRIMITIVE_INFO_INIT (MAX_POWER , TPMI_INFO_MAX_MASK , 36 ,
726+ RAPL_DOMAIN_REG_INFO , POWER_UNIT , 0 ),
727+ [MIN_POWER ] = PRIMITIVE_INFO_INIT (MIN_POWER , TPMI_INFO_MIN_MASK , 18 ,
728+ RAPL_DOMAIN_REG_INFO , POWER_UNIT , 0 ),
729+ [MAX_TIME_WINDOW ] = PRIMITIVE_INFO_INIT (MAX_TIME_WINDOW , TPMI_INFO_MAX_TIME_WIN_MASK , 54 ,
730+ RAPL_DOMAIN_REG_INFO , TIME_UNIT , 0 ),
731+ [THROTTLED_TIME ] = PRIMITIVE_INFO_INIT (THROTTLED_TIME , PERF_STATUS_THROTTLE_TIME_MASK , 0 ,
732+ RAPL_DOMAIN_REG_PERF , TIME_UNIT , 0 ),
733+ /* non-hardware */
734+ [AVERAGE_POWER ] = PRIMITIVE_INFO_INIT (AVERAGE_POWER , 0 , 0 , 0 ,
735+ POWER_UNIT , RAPL_PRIMITIVE_DERIVED ),
736+ };
737+
670738static struct rapl_primitive_info * get_rpi (struct rapl_package * rp , int prim )
671739{
672740 struct rapl_primitive_info * rpi = rp -> priv -> rpi ;
@@ -686,6 +754,10 @@ static int rapl_config(struct rapl_package *rp)
686754 rp -> priv -> defaults = (void * )defaults_msr ;
687755 rp -> priv -> rpi = (void * )rpi_msr ;
688756 break ;
757+ case RAPL_IF_TPMI :
758+ rp -> priv -> defaults = (void * )& defaults_tpmi ;
759+ rp -> priv -> rpi = (void * )rpi_tpmi ;
760+ break ;
689761 default :
690762 return - EINVAL ;
691763 }
@@ -1046,6 +1118,49 @@ static u64 rapl_compute_time_window_atom(struct rapl_domain *rd, u64 value,
10461118 return value ;
10471119}
10481120
1121+ /* TPMI Unit register has different layout */
1122+ #define TPMI_POWER_UNIT_OFFSET POWER_UNIT_OFFSET
1123+ #define TPMI_POWER_UNIT_MASK POWER_UNIT_MASK
1124+ #define TPMI_ENERGY_UNIT_OFFSET 0x06
1125+ #define TPMI_ENERGY_UNIT_MASK 0x7C0
1126+ #define TPMI_TIME_UNIT_OFFSET 0x0C
1127+ #define TPMI_TIME_UNIT_MASK 0xF000
1128+
1129+ static int rapl_check_unit_tpmi (struct rapl_domain * rd )
1130+ {
1131+ struct reg_action ra ;
1132+ u32 value ;
1133+
1134+ ra .reg = rd -> regs [RAPL_DOMAIN_REG_UNIT ];
1135+ ra .mask = ~0 ;
1136+ if (rd -> rp -> priv -> read_raw (get_rid (rd -> rp ), & ra )) {
1137+ pr_err ("Failed to read power unit REG 0x%llx on %s:%s, exit.\n" ,
1138+ ra .reg , rd -> rp -> name , rd -> name );
1139+ return - ENODEV ;
1140+ }
1141+
1142+ value = (ra .value & TPMI_ENERGY_UNIT_MASK ) >> TPMI_ENERGY_UNIT_OFFSET ;
1143+ rd -> energy_unit = ENERGY_UNIT_SCALE * 1000000 / (1 << value );
1144+
1145+ value = (ra .value & TPMI_POWER_UNIT_MASK ) >> TPMI_POWER_UNIT_OFFSET ;
1146+ rd -> power_unit = 1000000 / (1 << value );
1147+
1148+ value = (ra .value & TPMI_TIME_UNIT_MASK ) >> TPMI_TIME_UNIT_OFFSET ;
1149+ rd -> time_unit = 1000000 / (1 << value );
1150+
1151+ pr_debug ("Core CPU %s:%s energy=%dpJ, time=%dus, power=%duW\n" ,
1152+ rd -> rp -> name , rd -> name , rd -> energy_unit , rd -> time_unit , rd -> power_unit );
1153+
1154+ return 0 ;
1155+ }
1156+
1157+ static const struct rapl_defaults defaults_tpmi = {
1158+ .check_unit = rapl_check_unit_tpmi ,
1159+ /* Reuse existing logic, ignore the PL_CLAMP failures and enable all Power Limits */
1160+ .set_floor_freq = set_floor_freq_default ,
1161+ .compute_time_window = rapl_compute_time_window_core ,
1162+ };
1163+
10491164static const struct rapl_defaults rapl_defaults_core = {
10501165 .floor_freq_reg_addr = 0 ,
10511166 .check_unit = rapl_check_unit_core ,
0 commit comments