mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
docs: thermal: convert to ReST
Rename the thermal documentation files to ReST, add an index for them and adjust in order to produce a nice html output via the Sphinx build system. At its new index.rst, let's add a :orphan: while this is not linked to the main index.rst file, in order to avoid build warnings. Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> Acked-by: Zhang Rui <rui.zhang@intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
This commit is contained in:
committed by
Zhang Rui
parent
57c5b2ec90
commit
6bbe6f5732
+27
-12
@@ -1,5 +1,6 @@
|
||||
=======================
|
||||
CPU cooling APIs How To
|
||||
===================================
|
||||
=======================
|
||||
|
||||
Written by Amit Daniel Kachhap <amit.kachhap@linaro.org>
|
||||
|
||||
@@ -8,40 +9,54 @@ Updated: 6 Jan 2015
|
||||
Copyright (c) 2012 Samsung Electronics Co., Ltd(http://www.samsung.com)
|
||||
|
||||
0. Introduction
|
||||
===============
|
||||
|
||||
The generic cpu cooling(freq clipping) provides registration/unregistration APIs
|
||||
to the caller. The binding of the cooling devices to the trip point is left for
|
||||
the user. The registration APIs returns the cooling device pointer.
|
||||
|
||||
1. cpu cooling APIs
|
||||
===================
|
||||
|
||||
1.1 cpufreq registration/unregistration APIs
|
||||
1.1.1 struct thermal_cooling_device *cpufreq_cooling_register(
|
||||
struct cpumask *clip_cpus)
|
||||
--------------------------------------------
|
||||
|
||||
::
|
||||
|
||||
struct thermal_cooling_device
|
||||
*cpufreq_cooling_register(struct cpumask *clip_cpus)
|
||||
|
||||
This interface function registers the cpufreq cooling device with the name
|
||||
"thermal-cpufreq-%x". This api can support multiple instances of cpufreq
|
||||
cooling devices.
|
||||
|
||||
clip_cpus: cpumask of cpus where the frequency constraints will happen.
|
||||
clip_cpus:
|
||||
cpumask of cpus where the frequency constraints will happen.
|
||||
|
||||
1.1.2 struct thermal_cooling_device *of_cpufreq_cooling_register(
|
||||
struct cpufreq_policy *policy)
|
||||
::
|
||||
|
||||
struct thermal_cooling_device
|
||||
*of_cpufreq_cooling_register(struct cpufreq_policy *policy)
|
||||
|
||||
This interface function registers the cpufreq cooling device with
|
||||
the name "thermal-cpufreq-%x" linking it with a device tree node, in
|
||||
order to bind it via the thermal DT code. This api can support multiple
|
||||
instances of cpufreq cooling devices.
|
||||
|
||||
policy: CPUFreq policy.
|
||||
policy:
|
||||
CPUFreq policy.
|
||||
|
||||
1.1.3 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
|
||||
|
||||
::
|
||||
|
||||
void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
|
||||
|
||||
This interface function unregisters the "thermal-cpufreq-%x" cooling device.
|
||||
|
||||
cdev: Cooling device pointer which has to be unregistered.
|
||||
|
||||
2. Power models
|
||||
===============
|
||||
|
||||
The power API registration functions provide a simple power model for
|
||||
CPUs. The current power is calculated as dynamic power (static power isn't
|
||||
@@ -65,9 +80,9 @@ For a given processor implementation the primary factors are:
|
||||
variation. In pathological cases this variation can be significant,
|
||||
but typically it is of a much lesser impact than the factors above.
|
||||
|
||||
A high level dynamic power consumption model may then be represented as:
|
||||
A high level dynamic power consumption model may then be represented as::
|
||||
|
||||
Pdyn = f(run) * Voltage^2 * Frequency * Utilisation
|
||||
Pdyn = f(run) * Voltage^2 * Frequency * Utilisation
|
||||
|
||||
f(run) here represents the described execution behaviour and its
|
||||
result has a units of Watts/Hz/Volt^2 (this often expressed in
|
||||
@@ -80,9 +95,9 @@ factors. Therefore, in initial implementation that contribution is
|
||||
represented as a constant coefficient. This is a simplification
|
||||
consistent with the relative contribution to overall power variation.
|
||||
|
||||
In this simplified representation our model becomes:
|
||||
In this simplified representation our model becomes::
|
||||
|
||||
Pdyn = Capacitance * Voltage^2 * Frequency * Utilisation
|
||||
Pdyn = Capacitance * Voltage^2 * Frequency * Utilisation
|
||||
|
||||
Where `capacitance` is a constant that represents an indicative
|
||||
running time dynamic power coefficient in fundamental units of
|
||||
@@ -1,8 +1,11 @@
|
||||
========================
|
||||
Kernel driver exynos_tmu
|
||||
=================
|
||||
========================
|
||||
|
||||
Supported chips:
|
||||
|
||||
* ARM SAMSUNG EXYNOS4, EXYNOS5 series of SoC
|
||||
|
||||
Datasheet: Not publicly available
|
||||
|
||||
Authors: Donggeun Kim <dg77.kim@samsung.com>
|
||||
@@ -19,32 +22,39 @@ Temperature can be taken from the temperature code.
|
||||
There are three equations converting from temperature to temperature code.
|
||||
|
||||
The three equations are:
|
||||
1. Two point trimming
|
||||
1. Two point trimming::
|
||||
|
||||
Tc = (T - 25) * (TI2 - TI1) / (85 - 25) + TI1
|
||||
|
||||
2. One point trimming
|
||||
2. One point trimming::
|
||||
|
||||
Tc = T + TI1 - 25
|
||||
|
||||
3. No trimming
|
||||
3. No trimming::
|
||||
|
||||
Tc = T + 50
|
||||
|
||||
Tc: Temperature code, T: Temperature,
|
||||
TI1: Trimming info for 25 degree Celsius (stored at TRIMINFO register)
|
||||
Tc:
|
||||
Temperature code, T: Temperature,
|
||||
TI1:
|
||||
Trimming info for 25 degree Celsius (stored at TRIMINFO register)
|
||||
Temperature code measured at 25 degree Celsius which is unchanged
|
||||
TI2: Trimming info for 85 degree Celsius (stored at TRIMINFO register)
|
||||
TI2:
|
||||
Trimming info for 85 degree Celsius (stored at TRIMINFO register)
|
||||
Temperature code measured at 85 degree Celsius which is unchanged
|
||||
|
||||
TMU(Thermal Management Unit) in EXYNOS4/5 generates interrupt
|
||||
when temperature exceeds pre-defined levels.
|
||||
The maximum number of configurable threshold is five.
|
||||
The threshold levels are defined as follows:
|
||||
The threshold levels are defined as follows::
|
||||
|
||||
Level_0: current temperature > trigger_level_0 + threshold
|
||||
Level_1: current temperature > trigger_level_1 + threshold
|
||||
Level_2: current temperature > trigger_level_2 + threshold
|
||||
Level_3: current temperature > trigger_level_3 + threshold
|
||||
|
||||
The threshold and each trigger_level are set
|
||||
through the corresponding registers.
|
||||
The threshold and each trigger_level are set
|
||||
through the corresponding registers.
|
||||
|
||||
When an interrupt occurs, this driver notify kernel thermal framework
|
||||
with the function exynos_report_trigger.
|
||||
@@ -54,24 +64,27 @@ it can be used to synchronize the cooling action.
|
||||
TMU driver description:
|
||||
-----------------------
|
||||
|
||||
The exynos thermal driver is structured as,
|
||||
The exynos thermal driver is structured as::
|
||||
|
||||
Kernel Core thermal framework
|
||||
(thermal_core.c, step_wise.c, cpu_cooling.c)
|
||||
^
|
||||
|
|
||||
|
|
||||
TMU configuration data -------> TMU Driver <------> Exynos Core thermal wrapper
|
||||
(exynos_tmu_data.c) (exynos_tmu.c) (exynos_thermal_common.c)
|
||||
(exynos_tmu_data.h) (exynos_tmu.h) (exynos_thermal_common.h)
|
||||
TMU configuration data -----> TMU Driver <----> Exynos Core thermal wrapper
|
||||
(exynos_tmu_data.c) (exynos_tmu.c) (exynos_thermal_common.c)
|
||||
(exynos_tmu_data.h) (exynos_tmu.h) (exynos_thermal_common.h)
|
||||
|
||||
a) TMU configuration data: This consist of TMU register offsets/bitfields
|
||||
a) TMU configuration data:
|
||||
This consist of TMU register offsets/bitfields
|
||||
described through structure exynos_tmu_registers. Also several
|
||||
other platform data (struct exynos_tmu_platform_data) members
|
||||
are used to configure the TMU.
|
||||
b) TMU driver: This component initialises the TMU controller and sets different
|
||||
b) TMU driver:
|
||||
This component initialises the TMU controller and sets different
|
||||
thresholds. It invokes core thermal implementation with the call
|
||||
exynos_report_trigger.
|
||||
c) Exynos Core thermal wrapper: This provides 3 wrapper function to use the
|
||||
c) Exynos Core thermal wrapper:
|
||||
This provides 3 wrapper function to use the
|
||||
Kernel core thermal framework. They are exynos_unregister_thermal,
|
||||
exynos_register_thermal and exynos_report_trigger.
|
||||
@@ -1,53 +0,0 @@
|
||||
EXYNOS EMULATION MODE
|
||||
========================
|
||||
|
||||
Copyright (C) 2012 Samsung Electronics
|
||||
|
||||
Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal management unit.
|
||||
Thermal emulation mode supports software debug for TMU's operation. User can set temperature
|
||||
manually with software code and TMU will read current temperature from user value not from
|
||||
sensor's value.
|
||||
|
||||
Enabling CONFIG_THERMAL_EMULATION option will make this support available.
|
||||
When it's enabled, sysfs node will be created as
|
||||
/sys/devices/virtual/thermal/thermal_zone'zone id'/emul_temp.
|
||||
|
||||
The sysfs node, 'emul_node', will contain value 0 for the initial state. When you input any
|
||||
temperature you want to update to sysfs node, it automatically enable emulation mode and
|
||||
current temperature will be changed into it.
|
||||
(Exynos also supports user changeable delay time which would be used to delay of
|
||||
changing temperature. However, this node only uses same delay of real sensing time, 938us.)
|
||||
|
||||
Exynos emulation mode requires synchronous of value changing and enabling. It means when you
|
||||
want to update the any value of delay or next temperature, then you have to enable emulation
|
||||
mode at the same time. (Or you have to keep the mode enabling.) If you don't, it fails to
|
||||
change the value to updated one and just use last succeessful value repeatedly. That's why
|
||||
this node gives users the right to change termerpature only. Just one interface makes it more
|
||||
simply to use.
|
||||
|
||||
Disabling emulation mode only requires writing value 0 to sysfs node.
|
||||
|
||||
|
||||
TEMP 120 |
|
||||
|
|
||||
100 |
|
||||
|
|
||||
80 |
|
||||
| +-----------
|
||||
60 | | |
|
||||
| +-------------| |
|
||||
40 | | | |
|
||||
| | | |
|
||||
20 | | | +----------
|
||||
| | | | |
|
||||
0 |______________|_____________|__________|__________|_________
|
||||
A A A A TIME
|
||||
|<----->| |<----->| |<----->| |
|
||||
| 938us | | | | | |
|
||||
emulation : 0 50 | 70 | 20 | 0
|
||||
current temp : sensor 50 70 20 sensor
|
||||
@@ -0,0 +1,61 @@
|
||||
=====================
|
||||
Exynos Emulation Mode
|
||||
=====================
|
||||
|
||||
Copyright (C) 2012 Samsung Electronics
|
||||
|
||||
Written by Jonghwa Lee <jonghwa3.lee@samsung.com>
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Exynos 4x12 (4212, 4412) and 5 series provide emulation mode for thermal
|
||||
management unit. Thermal emulation mode supports software debug for
|
||||
TMU's operation. User can set temperature manually with software code
|
||||
and TMU will read current temperature from user value not from sensor's
|
||||
value.
|
||||
|
||||
Enabling CONFIG_THERMAL_EMULATION option will make this support
|
||||
available. When it's enabled, sysfs node will be created as
|
||||
/sys/devices/virtual/thermal/thermal_zone'zone id'/emul_temp.
|
||||
|
||||
The sysfs node, 'emul_node', will contain value 0 for the initial state.
|
||||
When you input any temperature you want to update to sysfs node, it
|
||||
automatically enable emulation mode and current temperature will be
|
||||
changed into it.
|
||||
|
||||
(Exynos also supports user changeable delay time which would be used to
|
||||
delay of changing temperature. However, this node only uses same delay
|
||||
of real sensing time, 938us.)
|
||||
|
||||
Exynos emulation mode requires synchronous of value changing and
|
||||
enabling. It means when you want to update the any value of delay or
|
||||
next temperature, then you have to enable emulation mode at the same
|
||||
time. (Or you have to keep the mode enabling.) If you don't, it fails to
|
||||
change the value to updated one and just use last succeessful value
|
||||
repeatedly. That's why this node gives users the right to change
|
||||
termerpature only. Just one interface makes it more simply to use.
|
||||
|
||||
Disabling emulation mode only requires writing value 0 to sysfs node.
|
||||
|
||||
::
|
||||
|
||||
|
||||
TEMP 120 |
|
||||
|
|
||||
100 |
|
||||
|
|
||||
80 |
|
||||
| +-----------
|
||||
60 | | |
|
||||
| +-------------| |
|
||||
40 | | | |
|
||||
| | | |
|
||||
20 | | | +----------
|
||||
| | | | |
|
||||
0 |______________|_____________|__________|__________|_________
|
||||
A A A A TIME
|
||||
|<----->| |<----->| |<----->| |
|
||||
| 938us | | | | | |
|
||||
emulation : 0 50 | 70 | 20 | 0
|
||||
current temp: sensor 50 70 20 sensor
|
||||
@@ -0,0 +1,18 @@
|
||||
:orphan:
|
||||
|
||||
=======
|
||||
Thermal
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
cpu-cooling-api
|
||||
sysfs-api
|
||||
power_allocator
|
||||
|
||||
exynos_thermal
|
||||
exynos_thermal_emulation
|
||||
intel_powerclamp
|
||||
nouveau_thermal
|
||||
x86_pkg_temperature_thermal
|
||||
+90
-87
@@ -1,10 +1,13 @@
|
||||
=======================
|
||||
INTEL POWERCLAMP DRIVER
|
||||
=======================
|
||||
By: Arjan van de Ven <arjan@linux.intel.com>
|
||||
Jacob Pan <jacob.jun.pan@linux.intel.com>
|
||||
=======================
|
||||
Intel Powerclamp Driver
|
||||
=======================
|
||||
|
||||
By:
|
||||
- Arjan van de Ven <arjan@linux.intel.com>
|
||||
- Jacob Pan <jacob.jun.pan@linux.intel.com>
|
||||
|
||||
.. Contents:
|
||||
|
||||
Contents:
|
||||
(*) Introduction
|
||||
- Goals and Objectives
|
||||
|
||||
@@ -23,7 +26,6 @@ Contents:
|
||||
- Generic Thermal Layer (sysfs)
|
||||
- Kernel APIs (TBD)
|
||||
|
||||
============
|
||||
INTRODUCTION
|
||||
============
|
||||
|
||||
@@ -47,7 +49,6 @@ scalability, and user experience. In many cases, clear advantage is
|
||||
shown over taking the CPU offline or modulating the CPU clock.
|
||||
|
||||
|
||||
===================
|
||||
THEORY OF OPERATION
|
||||
===================
|
||||
|
||||
@@ -57,11 +58,12 @@ Idle Injection
|
||||
On modern Intel processors (Nehalem or later), package level C-state
|
||||
residency is available in MSRs, thus also available to the kernel.
|
||||
|
||||
These MSRs are:
|
||||
#define MSR_PKG_C2_RESIDENCY 0x60D
|
||||
#define MSR_PKG_C3_RESIDENCY 0x3F8
|
||||
#define MSR_PKG_C6_RESIDENCY 0x3F9
|
||||
#define MSR_PKG_C7_RESIDENCY 0x3FA
|
||||
These MSRs are::
|
||||
|
||||
#define MSR_PKG_C2_RESIDENCY 0x60D
|
||||
#define MSR_PKG_C3_RESIDENCY 0x3F8
|
||||
#define MSR_PKG_C6_RESIDENCY 0x3F9
|
||||
#define MSR_PKG_C7_RESIDENCY 0x3FA
|
||||
|
||||
If the kernel can also inject idle time to the system, then a
|
||||
closed-loop control system can be established that manages package
|
||||
@@ -96,19 +98,21 @@ are not masked. Tests show that the extra wakeups from scheduler tick
|
||||
have a dramatic impact on the effectiveness of the powerclamp driver
|
||||
on large scale systems (Westmere system with 80 processors).
|
||||
|
||||
CPU0
|
||||
____________ ____________
|
||||
kidle_inject/0 | sleep | mwait | sleep |
|
||||
_________| |________| |_______
|
||||
duration
|
||||
CPU1
|
||||
____________ ____________
|
||||
kidle_inject/1 | sleep | mwait | sleep |
|
||||
_________| |________| |_______
|
||||
^
|
||||
|
|
||||
|
|
||||
roundup(jiffies, interval)
|
||||
::
|
||||
|
||||
CPU0
|
||||
____________ ____________
|
||||
kidle_inject/0 | sleep | mwait | sleep |
|
||||
_________| |________| |_______
|
||||
duration
|
||||
CPU1
|
||||
____________ ____________
|
||||
kidle_inject/1 | sleep | mwait | sleep |
|
||||
_________| |________| |_______
|
||||
^
|
||||
|
|
||||
|
|
||||
roundup(jiffies, interval)
|
||||
|
||||
Only one CPU is allowed to collect statistics and update global
|
||||
control parameters. This CPU is referred to as the controlling CPU in
|
||||
@@ -148,7 +152,7 @@ b) determine the amount of compensation needed at each target ratio
|
||||
|
||||
Compensation to each target ratio consists of two parts:
|
||||
|
||||
a) steady state error compensation
|
||||
a) steady state error compensation
|
||||
This is to offset the error occurring when the system can
|
||||
enter idle without extra wakeups (such as external interrupts).
|
||||
|
||||
@@ -158,41 +162,42 @@ Compensation to each target ratio consists of two parts:
|
||||
slowing down CPU activities.
|
||||
|
||||
A debugfs file is provided for the user to examine compensation
|
||||
progress and results, such as on a Westmere system.
|
||||
[jacob@nex01 ~]$ cat
|
||||
/sys/kernel/debug/intel_powerclamp/powerclamp_calib
|
||||
controlling cpu: 0
|
||||
pct confidence steady dynamic (compensation)
|
||||
0 0 0 0
|
||||
1 1 0 0
|
||||
2 1 1 0
|
||||
3 3 1 0
|
||||
4 3 1 0
|
||||
5 3 1 0
|
||||
6 3 1 0
|
||||
7 3 1 0
|
||||
8 3 1 0
|
||||
...
|
||||
30 3 2 0
|
||||
31 3 2 0
|
||||
32 3 1 0
|
||||
33 3 2 0
|
||||
34 3 1 0
|
||||
35 3 2 0
|
||||
36 3 1 0
|
||||
37 3 2 0
|
||||
38 3 1 0
|
||||
39 3 2 0
|
||||
40 3 3 0
|
||||
41 3 1 0
|
||||
42 3 2 0
|
||||
43 3 1 0
|
||||
44 3 1 0
|
||||
45 3 2 0
|
||||
46 3 3 0
|
||||
47 3 0 0
|
||||
48 3 2 0
|
||||
49 3 3 0
|
||||
progress and results, such as on a Westmere system::
|
||||
|
||||
[jacob@nex01 ~]$ cat
|
||||
/sys/kernel/debug/intel_powerclamp/powerclamp_calib
|
||||
controlling cpu: 0
|
||||
pct confidence steady dynamic (compensation)
|
||||
0 0 0 0
|
||||
1 1 0 0
|
||||
2 1 1 0
|
||||
3 3 1 0
|
||||
4 3 1 0
|
||||
5 3 1 0
|
||||
6 3 1 0
|
||||
7 3 1 0
|
||||
8 3 1 0
|
||||
...
|
||||
30 3 2 0
|
||||
31 3 2 0
|
||||
32 3 1 0
|
||||
33 3 2 0
|
||||
34 3 1 0
|
||||
35 3 2 0
|
||||
36 3 1 0
|
||||
37 3 2 0
|
||||
38 3 1 0
|
||||
39 3 2 0
|
||||
40 3 3 0
|
||||
41 3 1 0
|
||||
42 3 2 0
|
||||
43 3 1 0
|
||||
44 3 1 0
|
||||
45 3 2 0
|
||||
46 3 3 0
|
||||
47 3 0 0
|
||||
48 3 2 0
|
||||
49 3 3 0
|
||||
|
||||
Calibration occurs during runtime. No offline method is available.
|
||||
Steady state compensation is used only when confidence levels of all
|
||||
@@ -217,9 +222,8 @@ keeps track of clamping kernel threads, even after they are migrated
|
||||
to other CPUs, after a CPU offline event.
|
||||
|
||||
|
||||
=====================
|
||||
Performance Analysis
|
||||
=====================
|
||||
====================
|
||||
This section describes the general performance data collected on
|
||||
multiple systems, including Westmere (80P) and Ivy Bridge (4P, 8P).
|
||||
|
||||
@@ -257,16 +261,15 @@ achieve up to 40% better performance per watt. (measured by a spin
|
||||
counter summed over per CPU counting threads spawned for all running
|
||||
CPUs).
|
||||
|
||||
====================
|
||||
Usage and Interfaces
|
||||
====================
|
||||
The powerclamp driver is registered to the generic thermal layer as a
|
||||
cooling device. Currently, it’s not bound to any thermal zones.
|
||||
cooling device. Currently, it’s not bound to any thermal zones::
|
||||
|
||||
jacob@chromoly:/sys/class/thermal/cooling_device14$ grep . *
|
||||
cur_state:0
|
||||
max_state:50
|
||||
type:intel_powerclamp
|
||||
jacob@chromoly:/sys/class/thermal/cooling_device14$ grep . *
|
||||
cur_state:0
|
||||
max_state:50
|
||||
type:intel_powerclamp
|
||||
|
||||
cur_state allows user to set the desired idle percentage. Writing 0 to
|
||||
cur_state will stop idle injection. Writing a value between 1 and
|
||||
@@ -278,9 +281,9 @@ cur_state returns value -1 instead of 0 which is to avoid confusing
|
||||
100% busy state with the disabled state.
|
||||
|
||||
Example usage:
|
||||
- To inject 25% idle time
|
||||
$ sudo sh -c "echo 25 > /sys/class/thermal/cooling_device80/cur_state
|
||||
"
|
||||
- To inject 25% idle time::
|
||||
|
||||
$ sudo sh -c "echo 25 > /sys/class/thermal/cooling_device80/cur_state
|
||||
|
||||
If the system is not busy and has more than 25% idle time already,
|
||||
then the powerclamp driver will not start idle injection. Using Top
|
||||
@@ -292,23 +295,23 @@ idle time is accounted as normal idle in that common code path is
|
||||
taken as the idle task.
|
||||
|
||||
In this example, 24.1% idle is shown. This helps the system admin or
|
||||
user determine the cause of slowdown, when a powerclamp driver is in action.
|
||||
user determine the cause of slowdown, when a powerclamp driver is in action::
|
||||
|
||||
|
||||
Tasks: 197 total, 1 running, 196 sleeping, 0 stopped, 0 zombie
|
||||
Cpu(s): 71.2%us, 4.7%sy, 0.0%ni, 24.1%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
|
||||
Mem: 3943228k total, 1689632k used, 2253596k free, 74960k buffers
|
||||
Swap: 4087804k total, 0k used, 4087804k free, 945336k cached
|
||||
Tasks: 197 total, 1 running, 196 sleeping, 0 stopped, 0 zombie
|
||||
Cpu(s): 71.2%us, 4.7%sy, 0.0%ni, 24.1%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
|
||||
Mem: 3943228k total, 1689632k used, 2253596k free, 74960k buffers
|
||||
Swap: 4087804k total, 0k used, 4087804k free, 945336k cached
|
||||
|
||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
||||
3352 jacob 20 0 262m 644 428 S 286 0.0 0:17.16 spin
|
||||
3341 root -51 0 0 0 0 D 25 0.0 0:01.62 kidle_inject/0
|
||||
3344 root -51 0 0 0 0 D 25 0.0 0:01.60 kidle_inject/3
|
||||
3342 root -51 0 0 0 0 D 25 0.0 0:01.61 kidle_inject/1
|
||||
3343 root -51 0 0 0 0 D 25 0.0 0:01.60 kidle_inject/2
|
||||
2935 jacob 20 0 696m 125m 35m S 5 3.3 0:31.11 firefox
|
||||
1546 root 20 0 158m 20m 6640 S 3 0.5 0:26.97 Xorg
|
||||
2100 jacob 20 0 1223m 88m 30m S 3 2.3 0:23.68 compiz
|
||||
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
|
||||
3352 jacob 20 0 262m 644 428 S 286 0.0 0:17.16 spin
|
||||
3341 root -51 0 0 0 0 D 25 0.0 0:01.62 kidle_inject/0
|
||||
3344 root -51 0 0 0 0 D 25 0.0 0:01.60 kidle_inject/3
|
||||
3342 root -51 0 0 0 0 D 25 0.0 0:01.61 kidle_inject/1
|
||||
3343 root -51 0 0 0 0 D 25 0.0 0:01.60 kidle_inject/2
|
||||
2935 jacob 20 0 696m 125m 35m S 5 3.3 0:31.11 firefox
|
||||
1546 root 20 0 158m 20m 6640 S 3 0.5 0:26.97 Xorg
|
||||
2100 jacob 20 0 1223m 88m 30m S 3 2.3 0:23.68 compiz
|
||||
|
||||
Tests have shown that by using the powerclamp driver as a cooling
|
||||
device, a PID based userspace thermal controller can manage to
|
||||
@@ -1,13 +1,15 @@
|
||||
=====================
|
||||
Kernel driver nouveau
|
||||
===================
|
||||
=====================
|
||||
|
||||
Supported chips:
|
||||
|
||||
* NV43+
|
||||
|
||||
Authors: Martin Peres (mupuf) <martin.peres@free.fr>
|
||||
|
||||
Description
|
||||
---------
|
||||
-----------
|
||||
|
||||
This driver allows to read the GPU core temperature, drive the GPU fan and
|
||||
set temperature alarms.
|
||||
@@ -19,20 +21,25 @@ interface is likely not to work. This document may then not cover your situation
|
||||
entirely.
|
||||
|
||||
Temperature management
|
||||
--------------------
|
||||
----------------------
|
||||
|
||||
Temperature is exposed under as a read-only HWMON attribute temp1_input.
|
||||
|
||||
In order to protect the GPU from overheating, Nouveau supports 4 configurable
|
||||
temperature thresholds:
|
||||
|
||||
* Fan_boost: Fan speed is set to 100% when reaching this temperature;
|
||||
* Downclock: The GPU will be downclocked to reduce its power dissipation;
|
||||
* Critical: The GPU is put on hold to further lower power dissipation;
|
||||
* Shutdown: Shut the computer down to protect your GPU.
|
||||
* Fan_boost:
|
||||
Fan speed is set to 100% when reaching this temperature;
|
||||
* Downclock:
|
||||
The GPU will be downclocked to reduce its power dissipation;
|
||||
* Critical:
|
||||
The GPU is put on hold to further lower power dissipation;
|
||||
* Shutdown:
|
||||
Shut the computer down to protect your GPU.
|
||||
|
||||
WARNING: Some of these thresholds may not be used by Nouveau depending
|
||||
on your chipset.
|
||||
WARNING:
|
||||
Some of these thresholds may not be used by Nouveau depending
|
||||
on your chipset.
|
||||
|
||||
The default value for these thresholds comes from the GPU's vbios. These
|
||||
thresholds can be configured thanks to the following HWMON attributes:
|
||||
@@ -46,19 +53,24 @@ NOTE: Remember that the values are stored as milli degrees Celsius. Don't forget
|
||||
to multiply!
|
||||
|
||||
Fan management
|
||||
------------
|
||||
--------------
|
||||
|
||||
Not all cards have a drivable fan. If you do, then the following HWMON
|
||||
attributes should be available:
|
||||
|
||||
* pwm1_enable: Current fan management mode (NONE, MANUAL or AUTO);
|
||||
* pwm1: Current PWM value (power percentage);
|
||||
* pwm1_min: The minimum PWM speed allowed;
|
||||
* pwm1_max: The maximum PWM speed allowed (bypassed when hitting Fan_boost);
|
||||
* pwm1_enable:
|
||||
Current fan management mode (NONE, MANUAL or AUTO);
|
||||
* pwm1:
|
||||
Current PWM value (power percentage);
|
||||
* pwm1_min:
|
||||
The minimum PWM speed allowed;
|
||||
* pwm1_max:
|
||||
The maximum PWM speed allowed (bypassed when hitting Fan_boost);
|
||||
|
||||
You may also have the following attribute:
|
||||
|
||||
* fan1_input: Speed in RPM of your fan.
|
||||
* fan1_input:
|
||||
Speed in RPM of your fan.
|
||||
|
||||
Your fan can be driven in different modes:
|
||||
|
||||
@@ -66,14 +78,16 @@ Your fan can be driven in different modes:
|
||||
* 1: The fan can be driven in manual (use pwm1 to change the speed);
|
||||
* 2; The fan is driven automatically depending on the temperature.
|
||||
|
||||
NOTE: Be sure to use the manual mode if you want to drive the fan speed manually
|
||||
NOTE:
|
||||
Be sure to use the manual mode if you want to drive the fan speed manually
|
||||
|
||||
NOTE2: When operating in manual mode outside the vbios-defined
|
||||
[PWM_min, PWM_max] range, the reported fan speed (RPM) may not be accurate
|
||||
depending on your hardware.
|
||||
NOTE2:
|
||||
When operating in manual mode outside the vbios-defined
|
||||
[PWM_min, PWM_max] range, the reported fan speed (RPM) may not be accurate
|
||||
depending on your hardware.
|
||||
|
||||
Bug reports
|
||||
---------
|
||||
-----------
|
||||
|
||||
Thermal management on Nouveau is new and may not work on all cards. If you have
|
||||
inquiries, please ping mupuf on IRC (#nouveau, freenode).
|
||||
+83
-59
@@ -1,3 +1,4 @@
|
||||
=================================
|
||||
Power allocator governor tunables
|
||||
=================================
|
||||
|
||||
@@ -25,36 +26,36 @@ temperature as the control input and power as the controlled output:
|
||||
P_max = k_p * e + k_i * err_integral + k_d * diff_err + sustainable_power
|
||||
|
||||
where
|
||||
e = desired_temperature - current_temperature
|
||||
err_integral is the sum of previous errors
|
||||
diff_err = e - previous_error
|
||||
- e = desired_temperature - current_temperature
|
||||
- err_integral is the sum of previous errors
|
||||
- diff_err = e - previous_error
|
||||
|
||||
It is similar to the one depicted below:
|
||||
It is similar to the one depicted below::
|
||||
|
||||
k_d
|
||||
|
|
||||
current_temp |
|
||||
| v
|
||||
| +----------+ +---+
|
||||
| +----->| diff_err |-->| X |------+
|
||||
| | +----------+ +---+ |
|
||||
| | | tdp actor
|
||||
| | k_i | | get_requested_power()
|
||||
| | | | | | |
|
||||
| | | | | | | ...
|
||||
v | v v v v v
|
||||
+---+ | +-------+ +---+ +---+ +---+ +----------+
|
||||
| S |-------+----->| sum e |----->| X |--->| S |-->| S |-->|power |
|
||||
+---+ | +-------+ +---+ +---+ +---+ |allocation|
|
||||
^ | ^ +----------+
|
||||
| | | | |
|
||||
| | +---+ | | |
|
||||
| +------->| X |-------------------+ v v
|
||||
| +---+ granted performance
|
||||
desired_temperature ^
|
||||
|
|
||||
|
|
||||
k_po/k_pu
|
||||
k_d
|
||||
|
|
||||
current_temp |
|
||||
| v
|
||||
| +----------+ +---+
|
||||
| +----->| diff_err |-->| X |------+
|
||||
| | +----------+ +---+ |
|
||||
| | | tdp actor
|
||||
| | k_i | | get_requested_power()
|
||||
| | | | | | |
|
||||
| | | | | | | ...
|
||||
v | v v v v v
|
||||
+---+ | +-------+ +---+ +---+ +---+ +----------+
|
||||
| S |-----+----->| sum e |----->| X |--->| S |-->| S |-->|power |
|
||||
+---+ | +-------+ +---+ +---+ +---+ |allocation|
|
||||
^ | ^ +----------+
|
||||
| | | | |
|
||||
| | +---+ | | |
|
||||
| +------->| X |-------------------+ v v
|
||||
| +---+ granted performance
|
||||
desired_temperature ^
|
||||
|
|
||||
|
|
||||
k_po/k_pu
|
||||
|
||||
Sustainable power
|
||||
-----------------
|
||||
@@ -73,7 +74,7 @@ is typically 2000mW, while on a 10" tablet is around 4500mW (may vary
|
||||
depending on screen size).
|
||||
|
||||
If you are using device tree, do add it as a property of the
|
||||
thermal-zone. For example:
|
||||
thermal-zone. For example::
|
||||
|
||||
thermal-zones {
|
||||
soc_thermal {
|
||||
@@ -85,7 +86,7 @@ thermal-zone. For example:
|
||||
Instead, if the thermal zone is registered from the platform code, pass a
|
||||
`thermal_zone_params` that has a `sustainable_power`. If no
|
||||
`thermal_zone_params` were being passed, then something like below
|
||||
will suffice:
|
||||
will suffice::
|
||||
|
||||
static const struct thermal_zone_params tz_params = {
|
||||
.sustainable_power = 3500,
|
||||
@@ -112,18 +113,18 @@ available capacity at a low temperature. On the other hand, a high
|
||||
value of `k_pu` will result in the governor granting very high power
|
||||
while temperature is low, and may lead to temperature overshooting.
|
||||
|
||||
The default value for `k_pu` is:
|
||||
The default value for `k_pu` is::
|
||||
|
||||
2 * sustainable_power / (desired_temperature - switch_on_temp)
|
||||
|
||||
This means that at `switch_on_temp` the output of the controller's
|
||||
proportional term will be 2 * `sustainable_power`. The default value
|
||||
for `k_po` is:
|
||||
for `k_po` is::
|
||||
|
||||
sustainable_power / (desired_temperature - switch_on_temp)
|
||||
|
||||
Focusing on the proportional and feed forward values of the PID
|
||||
controller equation we have:
|
||||
controller equation we have::
|
||||
|
||||
P_max = k_p * e + sustainable_power
|
||||
|
||||
@@ -134,21 +135,23 @@ is the desired one, then the proportional component is zero and
|
||||
thermal equilibrium under constant load. `sustainable_power` is only
|
||||
an estimate, which is the reason for closed-loop control such as this.
|
||||
|
||||
Expanding `k_pu` we get:
|
||||
P_max = 2 * sustainable_power * (T_set - T) / (T_set - T_on) +
|
||||
sustainable_power
|
||||
Expanding `k_pu` we get::
|
||||
|
||||
where
|
||||
T_set is the desired temperature
|
||||
T is the current temperature
|
||||
T_on is the switch on temperature
|
||||
P_max = 2 * sustainable_power * (T_set - T) / (T_set - T_on) +
|
||||
sustainable_power
|
||||
|
||||
where:
|
||||
|
||||
- T_set is the desired temperature
|
||||
- T is the current temperature
|
||||
- T_on is the switch on temperature
|
||||
|
||||
When the current temperature is the switch_on temperature, the above
|
||||
formula becomes:
|
||||
formula becomes::
|
||||
|
||||
P_max = 2 * sustainable_power * (T_set - T_on) / (T_set - T_on) +
|
||||
sustainable_power = 2 * sustainable_power + sustainable_power =
|
||||
3 * sustainable_power
|
||||
sustainable_power = 2 * sustainable_power + sustainable_power =
|
||||
3 * sustainable_power
|
||||
|
||||
Therefore, the proportional term alone linearly decreases power from
|
||||
3 * `sustainable_power` to `sustainable_power` as the temperature
|
||||
@@ -178,11 +181,18 @@ Cooling device power API
|
||||
Cooling devices controlled by this governor must supply the additional
|
||||
"power" API in their `cooling_device_ops`. It consists on three ops:
|
||||
|
||||
1. int get_requested_power(struct thermal_cooling_device *cdev,
|
||||
struct thermal_zone_device *tz, u32 *power);
|
||||
@cdev: The `struct thermal_cooling_device` pointer
|
||||
@tz: thermal zone in which we are currently operating
|
||||
@power: pointer in which to store the calculated power
|
||||
1. ::
|
||||
|
||||
int get_requested_power(struct thermal_cooling_device *cdev,
|
||||
struct thermal_zone_device *tz, u32 *power);
|
||||
|
||||
|
||||
@cdev:
|
||||
The `struct thermal_cooling_device` pointer
|
||||
@tz:
|
||||
thermal zone in which we are currently operating
|
||||
@power:
|
||||
pointer in which to store the calculated power
|
||||
|
||||
`get_requested_power()` calculates the power requested by the device
|
||||
in milliwatts and stores it in @power . It should return 0 on
|
||||
@@ -190,23 +200,37 @@ success, -E* on failure. This is currently used by the power
|
||||
allocator governor to calculate how much power to give to each cooling
|
||||
device.
|
||||
|
||||
2. int state2power(struct thermal_cooling_device *cdev, struct
|
||||
thermal_zone_device *tz, unsigned long state, u32 *power);
|
||||
@cdev: The `struct thermal_cooling_device` pointer
|
||||
@tz: thermal zone in which we are currently operating
|
||||
@state: A cooling device state
|
||||
@power: pointer in which to store the equivalent power
|
||||
2. ::
|
||||
|
||||
int state2power(struct thermal_cooling_device *cdev, struct
|
||||
thermal_zone_device *tz, unsigned long state,
|
||||
u32 *power);
|
||||
|
||||
@cdev:
|
||||
The `struct thermal_cooling_device` pointer
|
||||
@tz:
|
||||
thermal zone in which we are currently operating
|
||||
@state:
|
||||
A cooling device state
|
||||
@power:
|
||||
pointer in which to store the equivalent power
|
||||
|
||||
Convert cooling device state @state into power consumption in
|
||||
milliwatts and store it in @power. It should return 0 on success, -E*
|
||||
on failure. This is currently used by thermal core to calculate the
|
||||
maximum power that an actor can consume.
|
||||
|
||||
3. int power2state(struct thermal_cooling_device *cdev, u32 power,
|
||||
unsigned long *state);
|
||||
@cdev: The `struct thermal_cooling_device` pointer
|
||||
@power: power in milliwatts
|
||||
@state: pointer in which to store the resulting state
|
||||
3. ::
|
||||
|
||||
int power2state(struct thermal_cooling_device *cdev, u32 power,
|
||||
unsigned long *state);
|
||||
|
||||
@cdev:
|
||||
The `struct thermal_cooling_device` pointer
|
||||
@power:
|
||||
power in milliwatts
|
||||
@state:
|
||||
pointer in which to store the resulting state
|
||||
|
||||
Calculate a cooling device state that would make the device consume at
|
||||
most @power mW and store it in @state. It should return 0 on success,
|
||||
File diff suppressed because it is too large
Load Diff
+18
-10
@@ -1,19 +1,23 @@
|
||||
===================================
|
||||
Kernel driver: x86_pkg_temp_thermal
|
||||
===================
|
||||
===================================
|
||||
|
||||
Supported chips:
|
||||
|
||||
* x86: with package level thermal management
|
||||
|
||||
(Verify using: CPUID.06H:EAX[bit 6] =1)
|
||||
|
||||
Authors: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
|
||||
|
||||
Reference
|
||||
---
|
||||
---------
|
||||
|
||||
Intel® 64 and IA-32 Architectures Software Developer’s Manual (Jan, 2013):
|
||||
Chapter 14.6: PACKAGE LEVEL THERMAL MANAGEMENT
|
||||
|
||||
Description
|
||||
---------
|
||||
-----------
|
||||
|
||||
This driver register CPU digital temperature package level sensor as a thermal
|
||||
zone with maximum two user mode configurable trip points. Number of trip points
|
||||
@@ -25,23 +29,27 @@ take any action to control temperature.
|
||||
Threshold management
|
||||
--------------------
|
||||
Each package will register as a thermal zone under /sys/class/thermal.
|
||||
Example:
|
||||
/sys/class/thermal/thermal_zone1
|
||||
|
||||
Example::
|
||||
|
||||
/sys/class/thermal/thermal_zone1
|
||||
|
||||
This contains two trip points:
|
||||
|
||||
- trip_point_0_temp
|
||||
- trip_point_1_temp
|
||||
|
||||
User can set any temperature between 0 to TJ-Max temperature. Temperature units
|
||||
are in milli-degree Celsius. Refer to "Documentation/thermal/sysfs-api.txt" for
|
||||
are in milli-degree Celsius. Refer to "Documentation/thermal/sysfs-api.rst" for
|
||||
thermal sys-fs details.
|
||||
|
||||
Any value other than 0 in these trip points, can trigger thermal notifications.
|
||||
Setting 0, stops sending thermal notifications.
|
||||
|
||||
Thermal notifications: To get kobject-uevent notifications, set the thermal zone
|
||||
policy to "user_space". For example: echo -n "user_space" > policy
|
||||
|
||||
|
||||
Thermal notifications:
|
||||
To get kobject-uevent notifications, set the thermal zone
|
||||
policy to "user_space".
|
||||
|
||||
For example::
|
||||
|
||||
echo -n "user_space" > policy
|
||||
+1
-1
@@ -15618,7 +15618,7 @@ M: Viresh Kumar <viresh.kumar@linaro.org>
|
||||
M: Javi Merino <javi.merino@kernel.org>
|
||||
L: linux-pm@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/thermal/cpu-cooling-api.txt
|
||||
F: Documentation/thermal/cpu-cooling-api.rst
|
||||
F: drivers/thermal/cpu_cooling.c
|
||||
F: include/linux/cpu_cooling.h
|
||||
|
||||
|
||||
@@ -251,7 +251,7 @@ struct thermal_bind_params {
|
||||
* platform characterization. This value is relative to the
|
||||
* rest of the weights so a cooling device whose weight is
|
||||
* double that of another cooling device is twice as
|
||||
* effective. See Documentation/thermal/sysfs-api.txt for more
|
||||
* effective. See Documentation/thermal/sysfs-api.rst for more
|
||||
* information.
|
||||
*/
|
||||
int weight;
|
||||
@@ -259,7 +259,7 @@ struct thermal_bind_params {
|
||||
/*
|
||||
* This is a bit mask that gives the binding relation between this
|
||||
* thermal zone and cdev, for a particular trip point.
|
||||
* See Documentation/thermal/sysfs-api.txt for more information.
|
||||
* See Documentation/thermal/sysfs-api.rst for more information.
|
||||
*/
|
||||
int trip_mask;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user