1 // SPDX-License-Identifier: GPL-2.0-only
3 * intel_tcc.c - Library for Intel TCC (thermal control circuitry) MSR access
4 * Copyright (c) 2022, Intel Corporation.
7 #include <linux/errno.h>
8 #include <linux/intel_tcc.h>
12 * intel_tcc_get_tjmax() - returns the default TCC activation Temperature
13 * @cpu: cpu that the MSR should be run on, nagative value means any cpu.
15 * Get the TjMax value, which is the default thermal throttling or TCC
16 * activation temperature in degrees C.
18 * Return: Tjmax value in degrees C on success, negative error code otherwise.
20 int intel_tcc_get_tjmax(int cpu)
26 err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high);
28 err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high);
32 val = (low >> 16) & 0xff;
34 return val ? val : -ENODATA;
36 EXPORT_SYMBOL_NS_GPL(intel_tcc_get_tjmax, INTEL_TCC);
39 * intel_tcc_get_offset() - returns the TCC Offset value to Tjmax
40 * @cpu: cpu that the MSR should be run on, nagative value means any cpu.
42 * Get the TCC offset value to Tjmax. The effective thermal throttling or TCC
43 * activation temperature equals "Tjmax" - "TCC Offset", in degrees C.
45 * Return: Tcc offset value in degrees C on success, negative error code otherwise.
47 int intel_tcc_get_offset(int cpu)
53 err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high);
55 err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high);
59 return (low >> 24) & 0x3f;
61 EXPORT_SYMBOL_NS_GPL(intel_tcc_get_offset, INTEL_TCC);
64 * intel_tcc_set_offset() - set the TCC offset value to Tjmax
65 * @cpu: cpu that the MSR should be run on, nagative value means any cpu.
66 * @offset: TCC offset value in degree C
68 * Set the TCC Offset value to Tjmax. The effective thermal throttling or TCC
69 * activation temperature equals "Tjmax" - "TCC Offset", in degree C.
71 * Return: On success returns 0, negative error code otherwise.
74 int intel_tcc_set_offset(int cpu, int offset)
79 if (offset < 0 || offset > 0x3f)
83 err = rdmsr_safe(MSR_IA32_TEMPERATURE_TARGET, &low, &high);
85 err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &low, &high);
97 return wrmsr_safe(MSR_IA32_TEMPERATURE_TARGET, low, high);
99 return wrmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, low, high);
101 EXPORT_SYMBOL_NS_GPL(intel_tcc_set_offset, INTEL_TCC);
104 * intel_tcc_get_temp() - returns the current temperature
105 * @cpu: cpu that the MSR should be run on, nagative value means any cpu.
106 * @pkg: true: Package Thermal Sensor. false: Core Thermal Sensor.
108 * Get the current temperature returned by the CPU core/package level
109 * thermal sensor, in degrees C.
111 * Return: Temperature in degrees C on success, negative error code otherwise.
113 int intel_tcc_get_temp(int cpu, bool pkg)
116 u32 msr = pkg ? MSR_IA32_PACKAGE_THERM_STATUS : MSR_IA32_THERM_STATUS;
117 int tjmax, temp, err;
119 tjmax = intel_tcc_get_tjmax(cpu);
124 err = rdmsr_safe(msr, &low, &high);
126 err = rdmsr_safe_on_cpu(cpu, msr, &low, &high);
130 /* Temperature is beyond the valid thermal sensor range */
131 if (!(low & BIT(31)))
134 temp = tjmax - ((low >> 16) & 0x7f);
136 /* Do not allow negative CPU temperature */
137 return temp >= 0 ? temp : -ENODATA;
139 EXPORT_SYMBOL_NS_GPL(intel_tcc_get_temp, INTEL_TCC);