Skip to content

Commit 58374a3

Browse files
zhang-ruirafaeljw
authored andcommitted
thermal/x86_pkg_temp_thermal: Add support for handling dynamic tjmax
Tjmax value retrieved from MSR_IA32_TEMPERATURE_TARGET can be changed at runtime when the Intel SST-PP (Intel Speed Select Technology - Performance Profile) level is changed. Enhance the code to use updated tjmax when programming the thermal interrupt thresholds. Signed-off-by: Zhang Rui <[email protected]> Signed-off-by: Rafael J. Wysocki <[email protected]>
1 parent 983eb37 commit 58374a3

File tree

1 file changed

+19
-11
lines changed

1 file changed

+19
-11
lines changed

drivers/thermal/intel/x86_pkg_temp_thermal.c

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@ MODULE_PARM_DESC(notify_delay_ms,
4949
struct zone_device {
5050
int cpu;
5151
bool work_scheduled;
52-
u32 tj_max;
5352
u32 msr_pkg_therm_low;
5453
u32 msr_pkg_therm_high;
5554
struct delayed_work work;
@@ -125,7 +124,7 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd,
125124
struct zone_device *zonedev = tzd->devdata;
126125
unsigned long thres_reg_value;
127126
u32 mask, shift, eax, edx;
128-
int ret;
127+
int tj_max, ret;
129128

130129
if (trip >= MAX_NUMBER_OF_TRIPS)
131130
return -EINVAL;
@@ -138,14 +137,19 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd,
138137
shift = THERM_SHIFT_THRESHOLD0;
139138
}
140139

140+
tj_max = intel_tcc_get_tjmax(zonedev->cpu);
141+
if (tj_max < 0)
142+
return tj_max;
143+
tj_max *= 1000;
144+
141145
ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
142146
&eax, &edx);
143147
if (ret < 0)
144148
return ret;
145149

146150
thres_reg_value = (eax & mask) >> shift;
147151
if (thres_reg_value)
148-
*temp = zonedev->tj_max - thres_reg_value * 1000;
152+
*temp = tj_max - thres_reg_value * 1000;
149153
else
150154
*temp = THERMAL_TEMP_INVALID;
151155
pr_debug("sys_get_trip_temp %d\n", *temp);
@@ -158,9 +162,14 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
158162
{
159163
struct zone_device *zonedev = tzd->devdata;
160164
u32 l, h, mask, shift, intr;
161-
int ret;
165+
int tj_max, ret;
162166

163-
if (trip >= MAX_NUMBER_OF_TRIPS || temp >= zonedev->tj_max)
167+
tj_max = intel_tcc_get_tjmax(zonedev->cpu);
168+
if (tj_max < 0)
169+
return tj_max;
170+
tj_max *= 1000;
171+
172+
if (trip >= MAX_NUMBER_OF_TRIPS || temp >= tj_max)
164173
return -EINVAL;
165174

166175
ret = rdmsr_on_cpu(zonedev->cpu, MSR_IA32_PACKAGE_THERM_INTERRUPT,
@@ -185,7 +194,7 @@ sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, int temp)
185194
if (!temp) {
186195
l &= ~intr;
187196
} else {
188-
l |= (zonedev->tj_max - temp)/1000 << shift;
197+
l |= (tj_max - temp)/1000 << shift;
189198
l |= intr;
190199
}
191200

@@ -307,7 +316,7 @@ static int pkg_thermal_notify(u64 msr_val)
307316
static int pkg_temp_thermal_device_add(unsigned int cpu)
308317
{
309318
int id = topology_logical_die_id(cpu);
310-
u32 tj_max, eax, ebx, ecx, edx;
319+
u32 eax, ebx, ecx, edx;
311320
struct zone_device *zonedev;
312321
int thres_count, err;
313322

@@ -321,17 +330,16 @@ static int pkg_temp_thermal_device_add(unsigned int cpu)
321330

322331
thres_count = clamp_val(thres_count, 0, MAX_NUMBER_OF_TRIPS);
323332

324-
tj_max = intel_tcc_get_tjmax(cpu);
325-
if (tj_max < 0)
326-
return tj_max;
333+
err = intel_tcc_get_tjmax(cpu);
334+
if (err < 0)
335+
return err;
327336

328337
zonedev = kzalloc(sizeof(*zonedev), GFP_KERNEL);
329338
if (!zonedev)
330339
return -ENOMEM;
331340

332341
INIT_DELAYED_WORK(&zonedev->work, pkg_temp_thermal_threshold_work_fn);
333342
zonedev->cpu = cpu;
334-
zonedev->tj_max = tj_max;
335343
zonedev->tzone = thermal_zone_device_register("x86_pkg_temp",
336344
thres_count,
337345
(thres_count == MAX_NUMBER_OF_TRIPS) ? 0x03 : 0x01,

0 commit comments

Comments
 (0)