75
75
#define PSYS_TIME_WINDOW1_MASK (0x7FULL<<19)
76
76
#define PSYS_TIME_WINDOW2_MASK (0x7FULL<<51)
77
77
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
+
78
87
/* Non HW constants */
79
88
#define RAPL_PRIMITIVE_DERIVED BIT(1) /* not from raw data */
80
89
#define RAPL_PRIMITIVE_DUMMY BIT(2)
@@ -119,6 +128,19 @@ static bool is_pl_valid(struct rapl_domain *rd, int pl)
119
128
120
129
static int get_pl_lock_prim (struct rapl_domain * rd , int pl )
121
130
{
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
+
122
144
/*
123
145
* Power Limit register that supports two power limits has a different
124
146
* 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)
134
156
case POWER_LIMIT1 :
135
157
if (prim == PL_ENABLE )
136
158
return PL1_ENABLE ;
137
- if (prim == PL_CLAMP )
159
+ if (prim == PL_CLAMP && rd -> rp -> priv -> type != RAPL_IF_TPMI )
138
160
return PL1_CLAMP ;
139
161
if (prim == PL_LIMIT )
140
162
return POWER_LIMIT1 ;
@@ -148,7 +170,7 @@ static int get_pl_prim(struct rapl_domain *rd, int pl, enum pl_prims prim)
148
170
case POWER_LIMIT2 :
149
171
if (prim == PL_ENABLE )
150
172
return PL2_ENABLE ;
151
- if (prim == PL_CLAMP )
173
+ if (prim == PL_CLAMP && rd -> rp -> priv -> type != RAPL_IF_TPMI )
152
174
return PL2_CLAMP ;
153
175
if (prim == PL_LIMIT )
154
176
return POWER_LIMIT2 ;
@@ -167,6 +189,8 @@ static int get_pl_prim(struct rapl_domain *rd, int pl, enum pl_prims prim)
167
189
/* PL4 would be around two times PL2, use same prim as PL2. */
168
190
if (prim == PL_MAX_POWER )
169
191
return MAX_POWER ;
192
+ if (prim == PL_LOCK )
193
+ return get_pl_lock_prim (rd , pl );
170
194
return - EINVAL ;
171
195
default :
172
196
return - EINVAL ;
@@ -187,6 +211,7 @@ struct rapl_defaults {
187
211
bool spr_psys_bits ;
188
212
};
189
213
static struct rapl_defaults * defaults_msr ;
214
+ static const struct rapl_defaults defaults_tpmi ;
190
215
191
216
static struct rapl_defaults * get_defaults (struct rapl_package * rp )
192
217
{
@@ -610,6 +635,7 @@ static u64 rapl_unit_xlate(struct rapl_domain *rd, enum unit_type type,
610
635
return div64_u64 (value , scale );
611
636
}
612
637
638
+ /* RAPL primitives for MSR and MMIO I/F */
613
639
static struct rapl_primitive_info rpi_msr [NR_RAPL_PRIMITIVES ] = {
614
640
/* name, mask, shift, msr index, unit divisor */
615
641
[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] = {
667
693
RAPL_PRIMITIVE_DERIVED ),
668
694
};
669
695
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
+
670
738
static struct rapl_primitive_info * get_rpi (struct rapl_package * rp , int prim )
671
739
{
672
740
struct rapl_primitive_info * rpi = rp -> priv -> rpi ;
@@ -686,6 +754,10 @@ static int rapl_config(struct rapl_package *rp)
686
754
rp -> priv -> defaults = (void * )defaults_msr ;
687
755
rp -> priv -> rpi = (void * )rpi_msr ;
688
756
break ;
757
+ case RAPL_IF_TPMI :
758
+ rp -> priv -> defaults = (void * )& defaults_tpmi ;
759
+ rp -> priv -> rpi = (void * )rpi_tpmi ;
760
+ break ;
689
761
default :
690
762
return - EINVAL ;
691
763
}
@@ -1046,6 +1118,49 @@ static u64 rapl_compute_time_window_atom(struct rapl_domain *rd, u64 value,
1046
1118
return value ;
1047
1119
}
1048
1120
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
+
1049
1164
static const struct rapl_defaults rapl_defaults_core = {
1050
1165
.floor_freq_reg_addr = 0 ,
1051
1166
.check_unit = rapl_check_unit_core ,
0 commit comments