Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 1 | * Thermal Framework Device Tree descriptor |
| 2 | |
| 3 | This file describes a generic binding to provide a way of |
| 4 | defining hardware thermal structure using device tree. |
| 5 | A thermal structure includes thermal zones and their components, |
| 6 | such as trip points, polling intervals, sensors and cooling devices |
| 7 | binding descriptors. |
| 8 | |
| 9 | The target of device tree thermal descriptors is to describe only |
| 10 | the hardware thermal aspects. The thermal device tree bindings are |
| 11 | not about how the system must control or which algorithm or policy |
| 12 | must be taken in place. |
| 13 | |
| 14 | There are five types of nodes involved to describe thermal bindings: |
| 15 | - thermal sensors: devices which may be used to take temperature |
| 16 | measurements. |
| 17 | - cooling devices: devices which may be used to dissipate heat. |
| 18 | - trip points: describe key temperatures at which cooling is recommended. The |
| 19 | set of points should be chosen based on hardware limits. |
| 20 | - cooling maps: used to describe links between trip points and cooling devices; |
| 21 | - thermal zones: used to describe thermal data within the hardware; |
| 22 | |
| 23 | The following is a description of each of these node types. |
| 24 | |
| 25 | * Thermal sensor devices |
| 26 | |
| 27 | Thermal sensor devices are nodes providing temperature sensing capabilities on |
| 28 | thermal zones. Typical devices are I2C ADC converters and bandgaps. These are |
| 29 | nodes providing temperature data to thermal zones. Thermal sensor devices may |
| 30 | control one or more internal sensors. |
| 31 | |
| 32 | Required property: |
| 33 | - #thermal-sensor-cells: Used to provide sensor device specific information |
| 34 | Type: unsigned while referring to it. Typically 0 on thermal sensor |
| 35 | Size: one cell nodes with only one sensor, and at least 1 on nodes |
| 36 | with several internal sensors, in order |
| 37 | to identify uniquely the sensor instances within |
| 38 | the IC. See thermal zone binding for more details |
| 39 | on how consumers refer to sensor devices. |
| 40 | |
| 41 | * Cooling device nodes |
| 42 | |
| 43 | Cooling devices are nodes providing control on power dissipation. There |
| 44 | are essentially two ways to provide control on power dissipation. First |
| 45 | is by means of regulating device performance, which is known as passive |
| 46 | cooling. A typical passive cooling is a CPU that has dynamic voltage and |
| 47 | frequency scaling (DVFS), and uses lower frequencies as cooling states. |
| 48 | Second is by means of activating devices in order to remove |
| 49 | the dissipated heat, which is known as active cooling, e.g. regulating |
| 50 | fan speeds. In both cases, cooling devices shall have a way to determine |
| 51 | the state of cooling in which the device is. |
| 52 | |
| 53 | Any cooling device has a range of cooling states (i.e. different levels |
| 54 | of heat dissipation). For example a fan's cooling states correspond to |
| 55 | the different fan speeds possible. Cooling states are referred to by |
| 56 | single unsigned integers, where larger numbers mean greater heat |
| 57 | dissipation. The precise set of cooling states associated with a device |
Punit Agrawal | eb168b7 | 2015-09-08 12:20:48 +0100 | [diff] [blame] | 58 | (as referred to by the cooling-min-level and cooling-max-level |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 59 | properties) should be defined in a particular device's binding. |
| 60 | For more examples of cooling devices, refer to the example sections below. |
| 61 | |
| 62 | Required properties: |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 63 | - #cooling-cells: Used to provide cooling device specific information |
| 64 | Type: unsigned while referring to it. Must be at least 2, in order |
Caesar Wang | 55f2ac3 | 2016-05-03 20:07:41 +0800 | [diff] [blame] | 65 | Size: one cell to specify minimum and maximum cooling state used |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 66 | in the reference. The first cell is the minimum |
| 67 | cooling state requested and the second cell is |
| 68 | the maximum cooling state requested in the reference. |
| 69 | See Cooling device maps section below for more details |
| 70 | on how consumers refer to cooling devices. |
| 71 | |
Punit Agrawal | 9fa04fb | 2015-09-08 12:20:49 +0100 | [diff] [blame] | 72 | Optional properties: |
| 73 | - cooling-min-level: An integer indicating the smallest |
| 74 | Type: unsigned cooling state accepted. Typically 0. |
| 75 | Size: one cell |
| 76 | |
| 77 | - cooling-max-level: An integer indicating the largest |
| 78 | Type: unsigned cooling state accepted. |
| 79 | Size: one cell |
| 80 | |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 81 | * Trip points |
| 82 | |
| 83 | The trip node is a node to describe a point in the temperature domain |
| 84 | in which the system takes an action. This node describes just the point, |
| 85 | not the action. |
| 86 | |
| 87 | Required properties: |
| 88 | - temperature: An integer indicating the trip temperature level, |
| 89 | Type: signed in millicelsius. |
| 90 | Size: one cell |
| 91 | |
| 92 | - hysteresis: A low hysteresis value on temperature property (above). |
| 93 | Type: unsigned This is a relative value, in millicelsius. |
| 94 | Size: one cell |
| 95 | |
| 96 | - type: a string containing the trip type. Expected values are: |
| 97 | "active": A trip point to enable active cooling |
| 98 | "passive": A trip point to enable passive cooling |
| 99 | "hot": A trip point to notify emergency |
| 100 | "critical": Hardware not reliable. |
| 101 | Type: string |
| 102 | |
| 103 | * Cooling device maps |
| 104 | |
| 105 | The cooling device maps node is a node to describe how cooling devices |
| 106 | get assigned to trip points of the zone. The cooling devices are expected |
| 107 | to be loaded in the target system. |
| 108 | |
| 109 | Required properties: |
| 110 | - cooling-device: A phandle of a cooling device with its specifier, |
| 111 | Type: phandle + referring to which cooling device is used in this |
| 112 | cooling specifier binding. In the cooling specifier, the first cell |
| 113 | is the minimum cooling state and the second cell |
| 114 | is the maximum cooling state used in this map. |
| 115 | - trip: A phandle of a trip point node within the same thermal |
| 116 | Type: phandle of zone. |
| 117 | trip point node |
| 118 | |
| 119 | Optional property: |
| 120 | - contribution: The cooling contribution to the thermal zone of the |
| 121 | Type: unsigned referred cooling device at the referred trip point. |
Caesar Wang | 55f2ac3 | 2016-05-03 20:07:41 +0800 | [diff] [blame] | 122 | Size: one cell The contribution is a ratio of the sum |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 123 | of all cooling contributions within a thermal zone. |
| 124 | |
| 125 | Note: Using the THERMAL_NO_LIMIT (-1UL) constant in the cooling-device phandle |
| 126 | limit specifier means: |
| 127 | (i) - minimum state allowed for minimum cooling state used in the reference. |
| 128 | (ii) - maximum state allowed for maximum cooling state used in the reference. |
| 129 | Refer to include/dt-bindings/thermal/thermal.h for definition of this constant. |
| 130 | |
| 131 | * Thermal zone nodes |
| 132 | |
| 133 | The thermal zone node is the node containing all the required info |
| 134 | for describing a thermal zone, including its cooling device bindings. The |
| 135 | thermal zone node must contain, apart from its own properties, one sub-node |
| 136 | containing trip nodes and one sub-node containing all the zone cooling maps. |
| 137 | |
| 138 | Required properties: |
| 139 | - polling-delay: The maximum number of milliseconds to wait between polls |
| 140 | Type: unsigned when checking this thermal zone. |
| 141 | Size: one cell |
| 142 | |
| 143 | - polling-delay-passive: The maximum number of milliseconds to wait |
| 144 | Type: unsigned between polls when performing passive cooling. |
| 145 | Size: one cell |
| 146 | |
| 147 | - thermal-sensors: A list of thermal sensor phandles and sensor specifier |
Caesar Wang | 55f2ac3 | 2016-05-03 20:07:41 +0800 | [diff] [blame] | 148 | Type: list of used while monitoring the thermal zone. |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 149 | phandles + sensor |
| 150 | specifier |
| 151 | |
| 152 | - trips: A sub-node which is a container of only trip point nodes |
| 153 | Type: sub-node required to describe the thermal zone. |
| 154 | |
| 155 | - cooling-maps: A sub-node which is a container of only cooling device |
| 156 | Type: sub-node map nodes, used to describe the relation between trips |
| 157 | and cooling devices. |
| 158 | |
| 159 | Optional property: |
| 160 | - coefficients: An array of integers (one signed cell) containing |
| 161 | Type: array coefficients to compose a linear relation between |
| 162 | Elem size: one cell the sensors listed in the thermal-sensors property. |
| 163 | Elem type: signed Coefficients defaults to 1, in case this property |
| 164 | is not specified. A simple linear polynomial is used: |
| 165 | Z = c0 * x0 + c1 + x1 + ... + c(n-1) * x(n-1) + cn. |
| 166 | |
| 167 | The coefficients are ordered and they match with sensors |
| 168 | by means of sensor ID. Additional coefficients are |
| 169 | interpreted as constant offset. |
| 170 | |
Punit Agrawal | 647f992 | 2015-02-26 19:00:32 +0000 | [diff] [blame] | 171 | - sustainable-power: An estimate of the sustainable power (in mW) that the |
| 172 | Type: unsigned thermal zone can dissipate at the desired |
| 173 | Size: one cell control temperature. For reference, the |
| 174 | sustainable power of a 4'' phone is typically |
| 175 | 2000mW, while on a 10'' tablet is around |
| 176 | 4500mW. |
| 177 | |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 178 | Note: The delay properties are bound to the maximum dT/dt (temperature |
| 179 | derivative over time) in two situations for a thermal zone: |
| 180 | (i) - when passive cooling is activated (polling-delay-passive); and |
| 181 | (ii) - when the zone just needs to be monitored (polling-delay) or |
| 182 | when active cooling is activated. |
| 183 | |
| 184 | The maximum dT/dt is highly bound to hardware power consumption and dissipation |
| 185 | capability. The delays should be chosen to account for said max dT/dt, |
| 186 | such that a device does not cross several trip boundaries unexpectedly |
| 187 | between polls. Choosing the right polling delays shall avoid having the |
| 188 | device in temperature ranges that may damage the silicon structures and |
| 189 | reduce silicon lifetime. |
| 190 | |
| 191 | * The thermal-zones node |
| 192 | |
| 193 | The "thermal-zones" node is a container for all thermal zone nodes. It shall |
| 194 | contain only sub-nodes describing thermal zones as in the section |
| 195 | "Thermal zone nodes". The "thermal-zones" node appears under "/". |
| 196 | |
| 197 | * Examples |
| 198 | |
| 199 | Below are several examples on how to use thermal data descriptors |
| 200 | using device tree bindings: |
| 201 | |
| 202 | (a) - CPU thermal zone |
| 203 | |
| 204 | The CPU thermal zone example below describes how to setup one thermal zone |
| 205 | using one single sensor as temperature source and many cooling devices and |
| 206 | power dissipation control sources. |
| 207 | |
| 208 | #include <dt-bindings/thermal/thermal.h> |
| 209 | |
| 210 | cpus { |
| 211 | /* |
| 212 | * Here is an example of describing a cooling device for a DVFS |
| 213 | * capable CPU. The CPU node describes its four OPPs. |
| 214 | * The cooling states possible are 0..3, and they are |
| 215 | * used as OPP indexes. The minimum cooling state is 0, which means |
| 216 | * all four OPPs can be available to the system. The maximum |
| 217 | * cooling state is 3, which means only the lowest OPPs (198MHz@0.85V) |
| 218 | * can be available in the system. |
| 219 | */ |
| 220 | cpu0: cpu@0 { |
| 221 | ... |
| 222 | operating-points = < |
| 223 | /* kHz uV */ |
| 224 | 970000 1200000 |
| 225 | 792000 1100000 |
| 226 | 396000 950000 |
| 227 | 198000 850000 |
| 228 | >; |
Punit Agrawal | eb168b7 | 2015-09-08 12:20:48 +0100 | [diff] [blame] | 229 | cooling-min-level = <0>; |
| 230 | cooling-max-level = <3>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 231 | #cooling-cells = <2>; /* min followed by max */ |
| 232 | }; |
| 233 | ... |
| 234 | }; |
| 235 | |
| 236 | &i2c1 { |
| 237 | ... |
| 238 | /* |
| 239 | * A simple fan controller which supports 10 speeds of operation |
| 240 | * (represented as 0-9). |
| 241 | */ |
| 242 | fan0: fan@0x48 { |
| 243 | ... |
Punit Agrawal | eb168b7 | 2015-09-08 12:20:48 +0100 | [diff] [blame] | 244 | cooling-min-level = <0>; |
| 245 | cooling-max-level = <9>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 246 | #cooling-cells = <2>; /* min followed by max */ |
| 247 | }; |
| 248 | }; |
| 249 | |
| 250 | ocp { |
| 251 | ... |
| 252 | /* |
| 253 | * A simple IC with a single bandgap temperature sensor. |
| 254 | */ |
| 255 | bandgap0: bandgap@0x0000ED00 { |
| 256 | ... |
| 257 | #thermal-sensor-cells = <0>; |
| 258 | }; |
| 259 | }; |
| 260 | |
| 261 | thermal-zones { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 262 | cpu_thermal: cpu-thermal { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 263 | polling-delay-passive = <250>; /* milliseconds */ |
| 264 | polling-delay = <1000>; /* milliseconds */ |
| 265 | |
| 266 | thermal-sensors = <&bandgap0>; |
| 267 | |
| 268 | trips { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 269 | cpu_alert0: cpu-alert0 { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 270 | temperature = <90000>; /* millicelsius */ |
| 271 | hysteresis = <2000>; /* millicelsius */ |
| 272 | type = "active"; |
| 273 | }; |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 274 | cpu_alert1: cpu-alert1 { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 275 | temperature = <100000>; /* millicelsius */ |
| 276 | hysteresis = <2000>; /* millicelsius */ |
| 277 | type = "passive"; |
| 278 | }; |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 279 | cpu_crit: cpu-crit { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 280 | temperature = <125000>; /* millicelsius */ |
| 281 | hysteresis = <2000>; /* millicelsius */ |
| 282 | type = "critical"; |
| 283 | }; |
| 284 | }; |
| 285 | |
| 286 | cooling-maps { |
| 287 | map0 { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 288 | trip = <&cpu_alert0>; |
| 289 | cooling-device = <&fan0 THERMAL_NO_LIMIT 4>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 290 | }; |
| 291 | map1 { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 292 | trip = <&cpu_alert1>; |
| 293 | cooling-device = <&fan0 5 THERMAL_NO_LIMIT>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 294 | }; |
| 295 | map2 { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 296 | trip = <&cpu_alert1>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 297 | cooling-device = |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 298 | <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 299 | }; |
| 300 | }; |
| 301 | }; |
| 302 | }; |
| 303 | |
| 304 | In the example above, the ADC sensor (bandgap0) at address 0x0000ED00 is |
| 305 | used to monitor the zone 'cpu-thermal' using its sole sensor. A fan |
| 306 | device (fan0) is controlled via I2C bus 1, at address 0x48, and has ten |
| 307 | different cooling states 0-9. It is used to remove the heat out of |
| 308 | the thermal zone 'cpu-thermal' using its cooling states |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 309 | from its minimum to 4, when it reaches trip point 'cpu_alert0' |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 310 | at 90C, as an example of active cooling. The same cooling device is used at |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 311 | 'cpu_alert1', but from 5 to its maximum state. The cpu@0 device is also |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 312 | linked to the same thermal zone, 'cpu-thermal', as a passive cooling device, |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 313 | using all its cooling states at trip point 'cpu_alert1', |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 314 | which is a trip point at 100C. On the thermal zone 'cpu-thermal', at the |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 315 | temperature of 125C, represented by the trip point 'cpu_crit', the silicon |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 316 | is not reliable anymore. |
| 317 | |
| 318 | (b) - IC with several internal sensors |
| 319 | |
| 320 | The example below describes how to deploy several thermal zones based off a |
| 321 | single sensor IC, assuming it has several internal sensors. This is a common |
| 322 | case on SoC designs with several internal IPs that may need different thermal |
| 323 | requirements, and thus may have their own sensor to monitor or detect internal |
| 324 | hotspots in their silicon. |
| 325 | |
| 326 | #include <dt-bindings/thermal/thermal.h> |
| 327 | |
| 328 | ocp { |
| 329 | ... |
| 330 | /* |
| 331 | * A simple IC with several bandgap temperature sensors. |
| 332 | */ |
| 333 | bandgap0: bandgap@0x0000ED00 { |
| 334 | ... |
| 335 | #thermal-sensor-cells = <1>; |
| 336 | }; |
| 337 | }; |
| 338 | |
| 339 | thermal-zones { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 340 | cpu_thermal: cpu-thermal { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 341 | polling-delay-passive = <250>; /* milliseconds */ |
| 342 | polling-delay = <1000>; /* milliseconds */ |
| 343 | |
| 344 | /* sensor ID */ |
| 345 | thermal-sensors = <&bandgap0 0>; |
| 346 | |
| 347 | trips { |
| 348 | /* each zone within the SoC may have its own trips */ |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 349 | cpu_alert: cpu-alert { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 350 | temperature = <100000>; /* millicelsius */ |
| 351 | hysteresis = <2000>; /* millicelsius */ |
| 352 | type = "passive"; |
| 353 | }; |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 354 | cpu_crit: cpu-crit { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 355 | temperature = <125000>; /* millicelsius */ |
| 356 | hysteresis = <2000>; /* millicelsius */ |
| 357 | type = "critical"; |
| 358 | }; |
| 359 | }; |
| 360 | |
| 361 | cooling-maps { |
| 362 | /* each zone within the SoC may have its own cooling */ |
| 363 | ... |
| 364 | }; |
| 365 | }; |
| 366 | |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 367 | gpu_thermal: gpu-thermal { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 368 | polling-delay-passive = <120>; /* milliseconds */ |
| 369 | polling-delay = <1000>; /* milliseconds */ |
| 370 | |
| 371 | /* sensor ID */ |
| 372 | thermal-sensors = <&bandgap0 1>; |
| 373 | |
| 374 | trips { |
| 375 | /* each zone within the SoC may have its own trips */ |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 376 | gpu_alert: gpu-alert { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 377 | temperature = <90000>; /* millicelsius */ |
| 378 | hysteresis = <2000>; /* millicelsius */ |
| 379 | type = "passive"; |
| 380 | }; |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 381 | gpu_crit: gpu-crit { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 382 | temperature = <105000>; /* millicelsius */ |
| 383 | hysteresis = <2000>; /* millicelsius */ |
| 384 | type = "critical"; |
| 385 | }; |
| 386 | }; |
| 387 | |
| 388 | cooling-maps { |
| 389 | /* each zone within the SoC may have its own cooling */ |
| 390 | ... |
| 391 | }; |
| 392 | }; |
| 393 | |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 394 | dsp_thermal: dsp-thermal { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 395 | polling-delay-passive = <50>; /* milliseconds */ |
| 396 | polling-delay = <1000>; /* milliseconds */ |
| 397 | |
| 398 | /* sensor ID */ |
| 399 | thermal-sensors = <&bandgap0 2>; |
| 400 | |
| 401 | trips { |
| 402 | /* each zone within the SoC may have its own trips */ |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 403 | dsp_alert: dsp-alert { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 404 | temperature = <90000>; /* millicelsius */ |
| 405 | hysteresis = <2000>; /* millicelsius */ |
| 406 | type = "passive"; |
| 407 | }; |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 408 | dsp_crit: gpu-crit { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 409 | temperature = <135000>; /* millicelsius */ |
| 410 | hysteresis = <2000>; /* millicelsius */ |
| 411 | type = "critical"; |
| 412 | }; |
| 413 | }; |
| 414 | |
| 415 | cooling-maps { |
| 416 | /* each zone within the SoC may have its own cooling */ |
| 417 | ... |
| 418 | }; |
| 419 | }; |
| 420 | }; |
| 421 | |
| 422 | In the example above, there is one bandgap IC which has the capability to |
| 423 | monitor three sensors. The hardware has been designed so that sensors are |
| 424 | placed on different places in the DIE to monitor different temperature |
| 425 | hotspots: one for CPU thermal zone, one for GPU thermal zone and the |
| 426 | other to monitor a DSP thermal zone. |
| 427 | |
| 428 | Thus, there is a need to assign each sensor provided by the bandgap IC |
| 429 | to different thermal zones. This is achieved by means of using the |
| 430 | #thermal-sensor-cells property and using the first cell of the sensor |
| 431 | specifier as sensor ID. In the example, then, <bandgap 0> is used to |
| 432 | monitor CPU thermal zone, <bandgap 1> is used to monitor GPU thermal |
| 433 | zone and <bandgap 2> is used to monitor DSP thermal zone. Each zone |
| 434 | may be uncorrelated, having its own dT/dt requirements, trips |
| 435 | and cooling maps. |
| 436 | |
| 437 | |
| 438 | (c) - Several sensors within one single thermal zone |
| 439 | |
| 440 | The example below illustrates how to use more than one sensor within |
| 441 | one thermal zone. |
| 442 | |
| 443 | #include <dt-bindings/thermal/thermal.h> |
| 444 | |
| 445 | &i2c1 { |
| 446 | ... |
| 447 | /* |
| 448 | * A simple IC with a single temperature sensor. |
| 449 | */ |
| 450 | adc: sensor@0x49 { |
| 451 | ... |
| 452 | #thermal-sensor-cells = <0>; |
| 453 | }; |
| 454 | }; |
| 455 | |
| 456 | ocp { |
| 457 | ... |
| 458 | /* |
| 459 | * A simple IC with a single bandgap temperature sensor. |
| 460 | */ |
| 461 | bandgap0: bandgap@0x0000ED00 { |
| 462 | ... |
| 463 | #thermal-sensor-cells = <0>; |
| 464 | }; |
| 465 | }; |
| 466 | |
| 467 | thermal-zones { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 468 | cpu_thermal: cpu-thermal { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 469 | polling-delay-passive = <250>; /* milliseconds */ |
| 470 | polling-delay = <1000>; /* milliseconds */ |
| 471 | |
| 472 | thermal-sensors = <&bandgap0>, /* cpu */ |
| 473 | <&adc>; /* pcb north */ |
| 474 | |
| 475 | /* hotspot = 100 * bandgap - 120 * adc + 484 */ |
Caesar Wang | 55f2ac3 | 2016-05-03 20:07:41 +0800 | [diff] [blame] | 476 | coefficients = <100 -120 484>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 477 | |
| 478 | trips { |
| 479 | ... |
| 480 | }; |
| 481 | |
| 482 | cooling-maps { |
| 483 | ... |
| 484 | }; |
| 485 | }; |
| 486 | }; |
| 487 | |
| 488 | In some cases, there is a need to use more than one sensor to extrapolate |
| 489 | a thermal hotspot in the silicon. The above example illustrates this situation. |
| 490 | For instance, it may be the case that a sensor external to CPU IP may be placed |
| 491 | close to CPU hotspot and together with internal CPU sensor, it is used |
| 492 | to determine the hotspot. Assuming this is the case for the above example, |
| 493 | the hypothetical extrapolation rule would be: |
| 494 | hotspot = 100 * bandgap - 120 * adc + 484 |
| 495 | |
| 496 | In other context, the same idea can be used to add fixed offset. For instance, |
| 497 | consider the hotspot extrapolation rule below: |
| 498 | hotspot = 1 * adc + 6000 |
| 499 | |
| 500 | In the above equation, the hotspot is always 6C higher than what is read |
| 501 | from the ADC sensor. The binding would be then: |
| 502 | thermal-sensors = <&adc>; |
| 503 | |
| 504 | /* hotspot = 1 * adc + 6000 */ |
Caesar Wang | 55f2ac3 | 2016-05-03 20:07:41 +0800 | [diff] [blame] | 505 | coefficients = <1 6000>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 506 | |
| 507 | (d) - Board thermal |
| 508 | |
| 509 | The board thermal example below illustrates how to setup one thermal zone |
| 510 | with many sensors and many cooling devices. |
| 511 | |
| 512 | #include <dt-bindings/thermal/thermal.h> |
| 513 | |
| 514 | &i2c1 { |
| 515 | ... |
| 516 | /* |
| 517 | * An IC with several temperature sensor. |
| 518 | */ |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 519 | adc_dummy: sensor@0x50 { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 520 | ... |
| 521 | #thermal-sensor-cells = <1>; /* sensor internal ID */ |
| 522 | }; |
| 523 | }; |
| 524 | |
| 525 | thermal-zones { |
| 526 | batt-thermal { |
| 527 | polling-delay-passive = <500>; /* milliseconds */ |
| 528 | polling-delay = <2500>; /* milliseconds */ |
| 529 | |
| 530 | /* sensor ID */ |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 531 | thermal-sensors = <&adc_dummy 4>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 532 | |
| 533 | trips { |
| 534 | ... |
| 535 | }; |
| 536 | |
| 537 | cooling-maps { |
| 538 | ... |
| 539 | }; |
| 540 | }; |
| 541 | |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 542 | board_thermal: board-thermal { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 543 | polling-delay-passive = <1000>; /* milliseconds */ |
| 544 | polling-delay = <2500>; /* milliseconds */ |
| 545 | |
| 546 | /* sensor ID */ |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 547 | thermal-sensors = <&adc_dummy 0>, /* pcb top edge */ |
| 548 | <&adc_dummy 1>, /* lcd */ |
| 549 | <&adc_dummy 2>; /* back cover */ |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 550 | /* |
| 551 | * An array of coefficients describing the sensor |
| 552 | * linear relation. E.g.: |
| 553 | * z = c1*x1 + c2*x2 + c3*x3 |
| 554 | */ |
| 555 | coefficients = <1200 -345 890>; |
| 556 | |
Punit Agrawal | 647f992 | 2015-02-26 19:00:32 +0000 | [diff] [blame] | 557 | sustainable-power = <2500>; |
| 558 | |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 559 | trips { |
| 560 | /* Trips are based on resulting linear equation */ |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 561 | cpu_trip: cpu-trip { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 562 | temperature = <60000>; /* millicelsius */ |
| 563 | hysteresis = <2000>; /* millicelsius */ |
| 564 | type = "passive"; |
| 565 | }; |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 566 | gpu_trip: gpu-trip { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 567 | temperature = <55000>; /* millicelsius */ |
| 568 | hysteresis = <2000>; /* millicelsius */ |
| 569 | type = "passive"; |
| 570 | } |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 571 | lcd_trip: lcp-trip { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 572 | temperature = <53000>; /* millicelsius */ |
| 573 | hysteresis = <2000>; /* millicelsius */ |
| 574 | type = "passive"; |
| 575 | }; |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 576 | crit_trip: crit-trip { |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 577 | temperature = <68000>; /* millicelsius */ |
| 578 | hysteresis = <2000>; /* millicelsius */ |
| 579 | type = "critical"; |
| 580 | }; |
| 581 | }; |
| 582 | |
| 583 | cooling-maps { |
| 584 | map0 { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 585 | trip = <&cpu_trip>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 586 | cooling-device = <&cpu0 0 2>; |
| 587 | contribution = <55>; |
| 588 | }; |
| 589 | map1 { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 590 | trip = <&gpu_trip>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 591 | cooling-device = <&gpu0 0 2>; |
| 592 | contribution = <20>; |
| 593 | }; |
| 594 | map2 { |
Srinivas Kandagatla | 252454f | 2015-01-28 17:13:35 +0000 | [diff] [blame] | 595 | trip = <&lcd_trip>; |
Eduardo Valentin | 4e5e470 | 2013-07-03 15:35:39 -0400 | [diff] [blame] | 596 | cooling-device = <&lcd0 5 10>; |
| 597 | contribution = <15>; |
| 598 | }; |
| 599 | }; |
| 600 | }; |
| 601 | }; |
| 602 | |
| 603 | The above example is a mix of previous examples, a sensor IP with several internal |
| 604 | sensors used to monitor different zones, one of them is composed by several sensors and |
| 605 | with different cooling devices. |