€•­±Œsphinx.addnodes”Œdocument”“”)�”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)�”}”(hhh]”(hŒ pending_xref”“”)�”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…”�”}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ6/translations/zh_CN/driver-api/thermal/power_allocator”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)�”}”(hhh]”hŒChinese (Traditional)”…”�”}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ6/translations/zh_TW/driver-api/thermal/power_allocator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒItalian”…”�”}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ6/translations/it_IT/driver-api/thermal/power_allocator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒJapanese”…”�”}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ6/translations/ja_JP/driver-api/thermal/power_allocator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒKorean”…”�”}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ6/translations/ko_KR/driver-api/thermal/power_allocator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒPortuguese (Brazilian)”…”�”}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ6/translations/pt_BR/driver-api/thermal/power_allocator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)�”}”(hhh]”hŒSpanish”…”�”}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ6/translations/sp_SP/driver-api/thermal/power_allocator”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)�”}”(hhh]”(hŒtitle”“”)�”}”(hŒ!Power allocator governor tunables”h]”hŒ!Power allocator governor tunables”…”�”}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒP/var/lib/git/docbuild/linux/Documentation/driver-api/thermal/power_allocator.rst”h´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒ Trip points”h]”hŒ Trip points”…”�”}”(hhÎh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhËh²hh³hÊh´KubhŒ paragraph”“”)�”}”(hŒHThe governor works optimally with the following two passive trip points:”h]”hŒHThe governor works optimally with the following two passive trip points:”…”�”}”(hhÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhhËh²hubhŒenumerated_list”“”)�”}”(hhh]”(hŒ list_item”“”)�”}”(hŒ—"switch on" trip point: temperature above which the governor control loop starts operating. This is the first passive trip point of the thermal zone. ”h]”hÝ)�”}”(hŒ–"switch on" trip point: temperature above which the governor control loop starts operating. This is the first passive trip point of the thermal zone.”h]”hŒšâ€œswitch onâ€� trip point: temperature above which the governor control loop starts operating. This is the first passive trip point of the thermal zone.”…”�”}”(hh÷h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K hhóubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhhîh²hh³hÊh´Nubhò)�”}”(hŒÏ"desired temperature" trip point: it should be higher than the "switch on" trip point. This the target temperature the governor is controlling for. This is the last passive trip point of the thermal zone. ”h]”hÝ)�”}”(hŒÎ"desired temperature" trip point: it should be higher than the "switch on" trip point. This the target temperature the governor is controlling for. This is the last passive trip point of the thermal zone.”h]”hŒÖ“desired temperatureâ€� trip point: it should be higher than the “switch onâ€� trip point. This the target temperature the governor is controlling for. This is the last passive trip point of the thermal zone.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Khj ubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhhîh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”Œenumtype”Œarabic”Œprefix”hŒsuffix”Œ.”uh1hìhhËh²hh³hÊh´K ubeh}”(h]”Œ trip-points”ah ]”h"]”Œ trip points”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒPID Controller”h]”hŒPID Controller”…”�”}”(hj9h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj6h²hh³hÊh´KubhÝ)�”}”(hŒ°The power allocator governor implements a Proportional-Integral-Derivative controller (PID controller) with temperature as the control input and power as the controlled output:”h]”hŒ°The power allocator governor implements a Proportional-Integral-Derivative controller (PID controller) with temperature as the control input and power as the controlled output:”…”�”}”(hjGh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Khj6h²hubhŒ block_quote”“”)�”}”(hŒJP_max = k_p * e + k_i * err_integral + k_d * diff_err + sustainable_power ”h]”hÝ)�”}”(hŒIP_max = k_p * e + k_i * err_integral + k_d * diff_err + sustainable_power”h]”hŒIP_max = k_p * e + k_i * err_integral + k_d * diff_err + sustainable_power”…”�”}”(hj[h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhjWubah}”(h]”h ]”h"]”h$]”h&]”uh1jUh³hÊh´Khj6h²hubhŒdefinition_list”“”)�”}”(hhh]”hŒdefinition_list_item”“”)�”}”(hŒ†where - e = desired_temperature - current_temperature - err_integral is the sum of previous errors - diff_err = e - previous_error ”h]”(hŒterm”“”)�”}”(hŒwhere”h]”hŒwhere”…”�”}”(hj|h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KhjvubhŒ definition”“”)�”}”(hhh]”hŒ bullet_list”“”)�”}”(hhh]”(hò)�”}”(hŒ-e = desired_temperature - current_temperature”h]”hÝ)�”}”(hj–h]”hŒ-e = desired_temperature - current_temperature”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Khj”ubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhj‘ubhò)�”}”(hŒ*err_integral is the sum of previous errors”h]”hÝ)�”}”(hj­h]”hŒ*err_integral is the sum of previous errors”…”�”}”(hj¯h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Khj«ubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhj‘ubhò)�”}”(hŒdiff_err = e - previous_error ”h]”hÝ)�”}”(hŒdiff_err = e - previous_error”h]”hŒdiff_err = e - previous_error”…”�”}”(hjÆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KhjÂubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhj‘ubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1j�h³hÊh´KhjŒubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhjvubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´Khjqubah}”(h]”h ]”h"]”h$]”h&]”uh1johj6h²hh³Nh´NubhÝ)�”}”(hŒ)It is similar to the one depicted below::”h]”hŒ(It is similar to the one depicted below:”…”�”}”(hjôh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K!hj6h²hubhŒ literal_block”“”)�”}”(hXF 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”h]”hXF 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”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1jh³hÊh´K#hj6h²hubeh}”(h]”Œpid-controller”ah ]”h"]”Œpid controller”ah$]”h&]”uh1hµhh·h²hh³hÊh´Kubh¶)�”}”(hhh]”(h»)�”}”(hŒSustainable power”h]”hŒSustainable power”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´K=ubhÝ)�”}”(hX¨An estimate of the sustainable dissipatable power (in mW) should be provided while registering the thermal zone. This estimates the sustained power that can be dissipated at the desired control temperature. This is the maximum sustained power for allocation at the desired maximum temperature. The actual sustained power can vary for a number of reasons. The closed loop controller will take care of variations such as environmental conditions, and some factors related to the speed-grade of the silicon. `sustainable_power` is therefore simply an estimate, and may be tuned to affect the aggressiveness of the thermal ramp. For reference, the sustainable power of a 4" phone is typically 2000mW, while on a 10" tablet is around 4500mW (may vary depending on screen size). It is possible to have the power value expressed in an abstract scale. The sustained power should be aligned to the scale used by the related cooling devices.”h]”(hXþAn estimate of the sustainable dissipatable power (in mW) should be provided while registering the thermal zone. This estimates the sustained power that can be dissipated at the desired control temperature. This is the maximum sustained power for allocation at the desired maximum temperature. The actual sustained power can vary for a number of reasons. The closed loop controller will take care of variations such as environmental conditions, and some factors related to the speed-grade of the silicon. ”…”�”}”(hj-h²hh³Nh´NubhŒtitle_reference”“”)�”}”(hŒ`sustainable_power`”h]”hŒsustainable_power”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj-ubhX› is therefore simply an estimate, and may be tuned to affect the aggressiveness of the thermal ramp. For reference, the sustainable power of a 4â€� phone is typically 2000mW, while on a 10â€� tablet is around 4500mW (may vary depending on screen size). It is possible to have the power value expressed in an abstract scale. The sustained power should be aligned to the scale used by the related cooling devices.”…”�”}”(hj-h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K?hjh²hubhÝ)�”}”(hŒYIf you are using device tree, do add it as a property of the thermal-zone. For example::”h]”hŒXIf you are using device tree, do add it as a property of the thermal-zone. For example:”…”�”}”(hjOh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KNhjh²hubj)�”}”(hŒ¼thermal-zones { soc_thermal { polling-delay = <1000>; polling-delay-passive = <100>; sustainable-power = <2500>; ...”h]”hŒ¼thermal-zones { soc_thermal { polling-delay = <1000>; polling-delay-passive = <100>; sustainable-power = <2500>; ...”…”�”}”hj]sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´KQhjh²hubhÝ)�”}”(hŒØ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::”h]”(hŒJInstead, if the thermal zone is registered from the platform code, pass a ”…”�”}”(hjkh²hh³Nh´Nubj6)�”}”(hŒ`thermal_zone_params`”h]”hŒthermal_zone_params”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjkubhŒ that has a ”…”�”}”(hjkh²hh³Nh´Nubj6)�”}”(hŒ`sustainable_power`”h]”hŒsustainable_power”…”�”}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjkubhŒ . If no ”…”�”}”(hjkh²hh³Nh´Nubj6)�”}”(hŒ`thermal_zone_params`”h]”hŒthermal_zone_params”…”�”}”(hj—h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjkubhŒ; were being passed, then something like below will suffice:”…”�”}”(hjkh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KXhjh²hubj)�”}”(hŒ[static const struct thermal_zone_params tz_params = { .sustainable_power = 3500, };”h]”hŒ[static const struct thermal_zone_params tz_params = { .sustainable_power = 3500, };”…”�”}”hj¯sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´K]hjh²hubhÝ)�”}”(hŒRand then pass `tz_params` as the 5th parameter to `thermal_zone_device_register()`”h]”(hŒand then pass ”…”�”}”(hj½h²hh³Nh´Nubj6)�”}”(hŒ `tz_params`”h]”hŒ tz_params”…”�”}”(hjÅh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj½ubhŒ as the 5th parameter to ”…”�”}”(hj½h²hh³Nh´Nubj6)�”}”(hŒ `thermal_zone_device_register()`”h]”hŒthermal_zone_device_register()”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj½ubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kahjh²hubeh}”(h]”Œsustainable-power”ah ]”h"]”Œsustainable power”ah$]”h&]”uh1hµhh·h²hh³hÊh´K=ubh¶)�”}”(hhh]”(h»)�”}”(hŒ k_po and k_pu”h]”hŒ k_po and k_pu”…”�”}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjóh²hh³hÊh´KeubhÝ)�”}”(hXÊThe implementation of the PID controller in the power allocator thermal governor allows the configuration of two proportional term constants: `k_po` and `k_pu`. `k_po` is the proportional term constant during temperature overshoot periods (current temperature is above "desired temperature" trip point). Conversely, `k_pu` is the proportional term constant during temperature undershoot periods (current temperature below "desired temperature" trip point).”h]”(hŒŽThe implementation of the PID controller in the power allocator thermal governor allows the configuration of two proportional term constants: ”…”�”}”(hjh²hh³Nh´Nubj6)�”}”(hŒ`k_po`”h]”hŒk_po”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjubhŒ and ”…”�”}”(hjh²hh³Nh´Nubj6)�”}”(hŒ`k_pu`”h]”hŒk_pu”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjubhŒ. ”…”�”}”(hjh²hh³Nh´Nubj6)�”}”(hŒ`k_po`”h]”hŒk_po”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjubhŒš is the proportional term constant during temperature overshoot periods (current temperature is above “desired temperatureâ€� trip point). Conversely, ”…”�”}”(hjh²hh³Nh´Nubj6)�”}”(hŒ`k_pu`”h]”hŒk_pu”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjubhŒŠ is the proportional term constant during temperature undershoot periods (current temperature below “desired temperatureâ€� trip point).”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kghjóh²hubhÝ)�”}”(hX”These controls are intended as the primary mechanism for configuring the permitted thermal "ramp" of the system. For instance, a lower `k_pu` value will provide a slower ramp, at the cost of capping 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.”h]”(hŒŒThese controls are intended as the primary mechanism for configuring the permitted thermal “rampâ€� of the system. For instance, a lower ”…”�”}”(hjZh²hh³Nh´Nubj6)�”}”(hŒ`k_pu`”h]”hŒk_pu”…”�”}”(hjbh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjZubhŒ‡ value will provide a slower ramp, at the cost of capping available capacity at a low temperature. On the other hand, a high value of ”…”�”}”(hjZh²hh³Nh´Nubj6)�”}”(hŒ`k_pu`”h]”hŒk_pu”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjZubhŒy will result in the governor granting very high power while temperature is low, and may lead to temperature overshooting.”…”�”}”(hjZh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kohjóh²hubhÝ)�”}”(hŒ!The default value for `k_pu` is::”h]”(hŒThe default value for ”…”�”}”(hjŒh²hh³Nh´Nubj6)�”}”(hŒ`k_pu`”h]”hŒk_pu”…”�”}”(hj”h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjŒubhŒ is:”…”�”}”(hjŒh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kvhjóh²hubj)�”}”(hŒ>2 * sustainable_power / (desired_temperature - switch_on_temp)”h]”hŒ>2 * sustainable_power / (desired_temperature - switch_on_temp)”…”�”}”hj¬sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´Kxhjóh²hubhÝ)�”}”(hŒ˜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::”h]”(hŒThis means that at ”…”�”}”(hjºh²hh³Nh´Nubj6)�”}”(hŒ`switch_on_temp`”h]”hŒswitch_on_temp”…”�”}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjºubhŒ@ the output of the controller’s proportional term will be 2 * ”…”�”}”(hjºh²hh³Nh´Nubj6)�”}”(hŒ`sustainable_power`”h]”hŒsustainable_power”…”�”}”(hjÔh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjºubhŒ. The default value for ”…”�”}”(hjºh²hh³Nh´Nubj6)�”}”(hŒ`k_po`”h]”hŒk_po”…”�”}”(hjæh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjºubhŒ is:”…”�”}”(hjºh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kzhjóh²hubj)�”}”(hŒ:sustainable_power / (desired_temperature - switch_on_temp)”h]”hŒ:sustainable_power / (desired_temperature - switch_on_temp)”…”�”}”hjþsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´K~hjóh²hubhÝ)�”}”(hŒ]Focusing on the proportional and feed forward values of the PID controller equation we have::”h]”hŒ\Focusing on the proportional and feed forward values of the PID controller equation we have:”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K€hjóh²hubj)�”}”(hŒ#P_max = k_p * e + sustainable_power”h]”hŒ#P_max = k_p * e + sustainable_power”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´Kƒhjóh²hubhÝ)�”}”(hX�The proportional term is proportional to the difference between the desired temperature and the current one. When the current temperature is the desired one, then the proportional component is zero and `P_max` = `sustainable_power`. That is, the system should operate in thermal equilibrium under constant load. `sustainable_power` is only an estimate, which is the reason for closed-loop control such as this.”h]”(hŒËThe proportional term is proportional to the difference between the desired temperature and the current one. When the current temperature is the desired one, then the proportional component is zero and ”…”�”}”(hj(h²hh³Nh´Nubj6)�”}”(hŒ`P_max`”h]”hŒP_max”…”�”}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj(ubhŒ = ”…”�”}”(hj(h²hh³Nh´Nubj6)�”}”(hŒ`sustainable_power`”h]”hŒsustainable_power”…”�”}”(hjBh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj(ubhŒS. That is, the system should operate in thermal equilibrium under constant load. ”…”�”}”(hj(h²hh³Nh´Nubj6)�”}”(hŒ`sustainable_power`”h]”hŒsustainable_power”…”�”}”(hjTh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj(ubhŒO is only an estimate, which is the reason for closed-loop control such as this.”…”�”}”(hj(h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K…hjóh²hubhÝ)�”}”(hŒExpanding `k_pu` we get::”h]”(hŒ Expanding ”…”�”}”(hjlh²hh³Nh´Nubj6)�”}”(hŒ`k_pu`”h]”hŒk_pu”…”�”}”(hjth²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjlubhŒ we get:”…”�”}”(hjlh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KŒhjóh²hubj)�”}”(hŒTP_max = 2 * sustainable_power * (T_set - T) / (T_set - T_on) + sustainable_power”h]”hŒTP_max = 2 * sustainable_power * (T_set - T) / (T_set - T_on) + sustainable_power”…”�”}”hjŒsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´KŽhjóh²hubhÝ)�”}”(hŒwhere:”h]”hŒwhere:”…”�”}”(hjšh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K‘hjóh²hubjV)�”}”(hŒf- T_set is the desired temperature - T is the current temperature - T_on is the switch on temperature ”h]”j�)�”}”(hhh]”(hò)�”}”(hŒ T_set is the desired temperature”h]”hÝ)�”}”(hj±h]”hŒ T_set is the desired temperature”…”�”}”(hj³h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K“hj¯ubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhj¬ubhò)�”}”(hŒT is the current temperature”h]”hÝ)�”}”(hjÈh]”hŒT is the current temperature”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K”hjÆubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhj¬ubhò)�”}”(hŒ"T_on is the switch on temperature ”h]”hÝ)�”}”(hŒ!T_on is the switch on temperature”h]”hŒ!T_on is the switch on temperature”…”�”}”(hjáh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K•hjÝubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhj¬ubeh}”(h]”h ]”h"]”h$]”h&]”jàjáuh1j�h³hÊh´K“hj¨ubah}”(h]”h ]”h"]”h$]”h&]”uh1jUh³hÊh´K“hjóh²hubhÝ)�”}”(hŒVWhen the current temperature is the switch_on temperature, the above formula becomes::”h]”hŒUWhen the current temperature is the switch_on temperature, the above formula becomes:”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K—hjóh²hubj)�”}”(hŒŸP_max = 2 * sustainable_power * (T_set - T_on) / (T_set - T_on) + sustainable_power = 2 * sustainable_power + sustainable_power = 3 * sustainable_power”h]”hŒŸP_max = 2 * sustainable_power * (T_set - T_on) / (T_set - T_on) + sustainable_power = 2 * sustainable_power + sustainable_power = 3 * sustainable_power”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´Kšhjóh²hubhÝ)�”}”(hŒÇTherefore, the proportional term alone linearly decreases power from 3 * `sustainable_power` to `sustainable_power` as the temperature rises from the switch on temperature to the desired temperature.”h]”(hŒITherefore, the proportional term alone linearly decreases power from 3 * ”…”�”}”(hjh²hh³Nh´Nubj6)�”}”(hŒ`sustainable_power`”h]”hŒsustainable_power”…”�”}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjubhŒ to ”…”�”}”(hjh²hh³Nh´Nubj6)�”}”(hŒ`sustainable_power`”h]”hŒsustainable_power”…”�”}”(hj7h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjubhŒT as the temperature rises from the switch on temperature to the desired temperature.”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kžhjóh²hubeh}”(h]”Œ k-po-and-k-pu”ah ]”h"]”Œ k_po and k_pu”ah$]”h&]”uh1hµhh·h²hh³hÊh´Keubh¶)�”}”(hhh]”(h»)�”}”(hŒk_i and integral_cutoff”h]”hŒk_i and integral_cutoff”…”�”}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjWh²hh³hÊh´K£ubhÝ)�”}”(hXû`k_i` configures the PID loop's integral term constant. This term allows the PID controller to compensate for long term drift and for the quantized nature of the output control: cooling devices can't set the exact power that the governor requests. When the temperature error is below `integral_cutoff`, errors are accumulated in the integral term. This term is then multiplied by `k_i` and the result added to the output of the controller. Typically `k_i` is set low (1 or 2) and `integral_cutoff` is 0.”h]”(j6)�”}”(hŒ`k_i`”h]”hŒk_i”…”�”}”(hjlh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjhubhX configures the PID loop’s integral term constant. This term allows the PID controller to compensate for long term drift and for the quantized nature of the output control: cooling devices can’t set the exact power that the governor requests. When the temperature error is below ”…”�”}”(hjhh²hh³Nh´Nubj6)�”}”(hŒ`integral_cutoff`”h]”hŒintegral_cutoff”…”�”}”(hj~h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjhubhŒP, errors are accumulated in the integral term. This term is then multiplied by ”…”�”}”(hjhh²hh³Nh´Nubj6)�”}”(hŒ`k_i`”h]”hŒk_i”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjhubhŒB and the result added to the output of the controller. Typically ”…”�”}”(hjhh²hh³Nh´Nubj6)�”}”(hŒ`k_i`”h]”hŒk_i”…”�”}”(hj¢h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjhubhŒ is set low (1 or 2) and ”…”�”}”(hjhh²hh³Nh´Nubj6)�”}”(hŒ`integral_cutoff`”h]”hŒintegral_cutoff”…”�”}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjhubhŒ is 0.”…”�”}”(hjhh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K¥hjWh²hubeh}”(h]”Œk-i-and-integral-cutoff”ah ]”h"]”Œk_i and integral_cutoff”ah$]”h&]”uh1hµhh·h²hh³hÊh´K£ubh¶)�”}”(hhh]”(h»)�”}”(hŒk_d”h]”hŒk_d”…”�”}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÔh²hh³hÊh´K¯ubhÝ)�”}”(hŒj`k_d` configures the PID loop's derivative term constant. It's recommended to leave it as the default: 0.”h]”(j6)�”}”(hŒ`k_d`”h]”hŒk_d”…”�”}”(hjéh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjåubhŒi configures the PID loop’s derivative term constant. It’s recommended to leave it as the default: 0.”…”�”}”(hjåh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K±hjÔh²hubh¶)�”}”(hhh]”(h»)�”}”(hŒCooling device power API”h]”hŒCooling device power API”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjh²hh³hÊh´KµubhÝ)�”}”(hŒŒCooling devices controlled by this governor must supply the additional "power" API in their `cooling_device_ops`. It consists on three ops:”h]”(hŒ`Cooling devices controlled by this governor must supply the additional “powerâ€� API in their ”…”�”}”(hjh²hh³Nh´Nubj6)�”}”(hŒ`cooling_device_ops`”h]”hŒcooling_device_ops”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjubhŒ. It consists on three ops:”…”�”}”(hjh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´K·hjh²hubhí)�”}”(hhh]”hò)�”}”(hŒ‰:: int get_requested_power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, u32 *power); ”h]”j)�”}”(hŒ�int get_requested_power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, u32 *power);”h]”hŒ�int get_requested_power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, u32 *power);”…”�”}”hj9sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´K¼hj5ubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhj2h²hh³hÊh´Nubah}”(h]”h ]”h"]”h$]”h&]”j)j*j+hj,j-uh1hìhjh²hh³hÊh´Kºubjp)�”}”(hhh]”(ju)�”}”(hŒ2@cdev: The `struct thermal_cooling_device` pointer”h]”(j{)�”}”(hŒ@cdev:”h]”hŒ@cdev:”…”�”}”(hjZh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KÀhjVubj‹)�”}”(hhh]”hÝ)�”}”(hŒ+The `struct thermal_cooling_device` pointer”h]”(hŒThe ”…”�”}”(hjkh²hh³Nh´Nubj6)�”}”(hŒ`struct thermal_cooling_device`”h]”hŒstruct thermal_cooling_device”…”�”}”(hjsh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjkubhŒ pointer”…”�”}”(hjkh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÁhjhubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhjVubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´KÀhjSubju)�”}”(hŒ5@tz: thermal zone in which we are currently operating”h]”(j{)�”}”(hŒ@tz:”h]”hŒ@tz:”…”�”}”(hj›h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KÂhj—ubj‹)�”}”(hhh]”hÝ)�”}”(hŒ0thermal zone in which we are currently operating”h]”hŒ0thermal zone in which we are currently operating”…”�”}”(hj¬h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÃhj©ubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhj—ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´KÂhjSh²hubju)�”}”(hŒ7@power: pointer in which to store the calculated power ”h]”(j{)�”}”(hŒ@power:”h]”hŒ@power:”…”�”}”(hjÊh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KÅhjÆubj‹)�”}”(hhh]”hÝ)�”}”(hŒ.pointer in which to store the calculated power”h]”hŒ.pointer in which to store the calculated power”…”�”}”(hjÛh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÅhjØubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhjÆubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´KÅhjSh²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1johjh²hh³hÊh´NubhÝ)�”}”(hX`get_requested_power()` calculates the power requested by the device in milliwatts and stores it in @power . It should return 0 on success, -E* on failure. This is currently used by the power allocator governor to calculate how much power to give to each cooling device.”h]”(j6)�”}”(hŒ`get_requested_power()`”h]”hŒget_requested_power()”…”�”}”(hjÿh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjûubhŒù calculates the power requested by the device in milliwatts and stores it in @power . It should return 0 on success, -E* on failure. This is currently used by the power allocator governor to calculate how much power to give to each cooling device.”…”�”}”(hjûh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÇhjh²hubhí)�”}”(hhh]”hò)�”}”(hŒª:: int state2power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, unsigned long state, u32 *power); ”h]”j)�”}”(hŒ–int state2power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, unsigned long state, u32 *power);”h]”hŒ–int state2power(struct thermal_cooling_device *cdev, struct thermal_zone_device *tz, unsigned long state, u32 *power);”…”�”}”hjsbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´KÏhjubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhjh²hh³hÊh´Nubah}”(h]”h ]”h"]”h$]”h&]”j)j*j+hj,j-Œstart”Kuh1hìhjh²hh³hÊh´KÍubjp)�”}”(hhh]”(ju)�”}”(hŒ2@cdev: The `struct thermal_cooling_device` pointer”h]”(j{)�”}”(hŒ@cdev:”h]”hŒ@cdev:”…”�”}”(hj@h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KÓhj<ubj‹)�”}”(hhh]”hÝ)�”}”(hŒ+The `struct thermal_cooling_device` pointer”h]”(hŒThe ”…”�”}”(hjQh²hh³Nh´Nubj6)�”}”(hŒ`struct thermal_cooling_device`”h]”hŒstruct thermal_cooling_device”…”�”}”(hjYh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjQubhŒ pointer”…”�”}”(hjQh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÔhjNubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhj<ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´KÓhj9ubju)�”}”(hŒ5@tz: thermal zone in which we are currently operating”h]”(j{)�”}”(hŒ@tz:”h]”hŒ@tz:”…”�”}”(hj�h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KÕhj}ubj‹)�”}”(hhh]”hÝ)�”}”(hŒ0thermal zone in which we are currently operating”h]”hŒ0thermal zone in which we are currently operating”…”�”}”(hj’h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÖhj�ubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhj}ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´KÕhj9h²hubju)�”}”(hŒ@state: A cooling device state”h]”(j{)�”}”(hŒ@state:”h]”hŒ@state:”…”�”}”(hj°h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´K×hj¬ubj‹)�”}”(hhh]”hÝ)�”}”(hŒA cooling device state”h]”hŒA cooling device state”…”�”}”(hjÁh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KØhj¾ubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhj¬ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´K×hj9h²hubju)�”}”(hŒ7@power: pointer in which to store the equivalent power ”h]”(j{)�”}”(hŒ@power:”h]”hŒ@power:”…”�”}”(hjßh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KÚhjÛubj‹)�”}”(hhh]”hÝ)�”}”(hŒ.pointer in which to store the equivalent power”h]”hŒ.pointer in which to store the equivalent power”…”�”}”(hjðh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÚhjíubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhjÛubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´KÚhj9h²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1johjh²hh³hÊh´NubhÝ)�”}”(hŒò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.”h]”hŒò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.”…”�”}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KÜhjh²hubhí)�”}”(hhh]”hò)�”}”(hŒu:: int power2state(struct thermal_cooling_device *cdev, u32 power, unsigned long *state); ”h]”j)�”}”(hŒfint power2state(struct thermal_cooling_device *cdev, u32 power, unsigned long *state);”h]”hŒfint power2state(struct thermal_cooling_device *cdev, u32 power, unsigned long *state);”…”�”}”hj%sbah}”(h]”h ]”h"]”h$]”h&]”jjuh1jh³hÊh´Kãhj!ubah}”(h]”h ]”h"]”h$]”h&]”uh1hñhjh²hh³hÊh´Nubah}”(h]”h ]”h"]”h$]”h&]”j)j*j+hj,j-j8Kuh1hìhjh²hh³hÊh´Káubjp)�”}”(hhh]”(ju)�”}”(hŒ2@cdev: The `struct thermal_cooling_device` pointer”h]”(j{)�”}”(hŒ@cdev:”h]”hŒ@cdev:”…”�”}”(hjFh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´KæhjBubj‹)�”}”(hhh]”hÝ)�”}”(hŒ+The `struct thermal_cooling_device` pointer”h]”(hŒThe ”…”�”}”(hjWh²hh³Nh´Nubj6)�”}”(hŒ`struct thermal_cooling_device`”h]”hŒstruct thermal_cooling_device”…”�”}”(hj_h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hjWubhŒ pointer”…”�”}”(hjWh²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KçhjTubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhjBubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´Kæhj?ubju)�”}”(hŒ@power: power in milliwatts”h]”(j{)�”}”(hŒ@power:”h]”hŒ@power:”…”�”}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´Kèhjƒubj‹)�”}”(hhh]”hÝ)�”}”(hŒpower in milliwatts”h]”hŒpower in milliwatts”…”�”}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kéhj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhjƒubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´Kèhj?h²hubju)�”}”(hŒ6@state: pointer in which to store the resulting state ”h]”(j{)�”}”(hŒ@state:”h]”hŒ@state:”…”�”}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jzh³hÊh´Këhj²ubj‹)�”}”(hhh]”hÝ)�”}”(hŒ-pointer in which to store the resulting state”h]”hŒ-pointer in which to store the resulting state”…”�”}”(hjÇh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´KëhjÄubah}”(h]”h ]”h"]”h$]”h&]”uh1jŠhj²ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jth³hÊh´Këhj?h²hubeh}”(h]”h ]”h"]”h$]”h&]”uh1johjh²hh³hÊh´NubhÝ)�”}”(hXÖ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, -E* on failure. This is currently used by the thermal core to convert a given power set by the power allocator governor to a state that the cooling device can set. It is a function because this conversion may depend on external factors that may change so this function should the best conversion given "current circumstances".”h]”hXÚ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, -E* on failure. This is currently used by the thermal core to convert a given power set by the power allocator governor to a state that the cooling device can set. It is a function because this conversion may depend on external factors that may change so this function should the best conversion given “current circumstancesâ€�.”…”�”}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Kíhjh²hubeh}”(h]”Œcooling-device-power-api”ah ]”h"]”Œcooling device power api”ah$]”h&]”uh1hµhjÔh²hh³hÊh´Kµubeh}”(h]”Œk-d”ah ]”h"]”Œk_d”ah$]”h&]”uh1hµhh·h²hh³hÊh´K¯ubh¶)�”}”(hhh]”(h»)�”}”(hŒCooling device weights”h]”hŒCooling device weights”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhj h²hh³hÊh´KöubhÝ)�”}”(hX Weights are a mechanism to bias the allocation among cooling devices. They express the relative power efficiency of different cooling devices. Higher weight can be used to express higher power efficiency. Weighting is relative such that if each cooling device has a weight of one they are considered equal. This is particularly useful in heterogeneous systems where two cooling devices may perform the same kind of compute, but with different efficiency. For example, a system with two different types of processors.”h]”hX Weights are a mechanism to bias the allocation among cooling devices. They express the relative power efficiency of different cooling devices. Higher weight can be used to express higher power efficiency. Weighting is relative such that if each cooling device has a weight of one they are considered equal. This is particularly useful in heterogeneous systems where two cooling devices may perform the same kind of compute, but with different efficiency. For example, a system with two different types of processors.”…”�”}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Køhj h²hubhÝ)�”}”(hX=If the thermal zone is registered using `thermal_zone_device_register()` (i.e., platform code), then weights are passed as part of the thermal zone's `thermal_bind_parameters`. If the platform is registered using device tree, then they are passed as the `contribution` property of each map in the `cooling-maps` node.”h]”(hŒ(If the thermal zone is registered using ”…”�”}”(hj$ h²hh³Nh´Nubj6)�”}”(hŒ `thermal_zone_device_register()`”h]”hŒthermal_zone_device_register()”…”�”}”(hj, h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj$ ubhŒP (i.e., platform code), then weights are passed as part of the thermal zone’s ”…”�”}”(hj$ h²hh³Nh´Nubj6)�”}”(hŒ`thermal_bind_parameters`”h]”hŒthermal_bind_parameters”…”�”}”(hj> h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj$ ubhŒO. If the platform is registered using device tree, then they are passed as the ”…”�”}”(hj$ h²hh³Nh´Nubj6)�”}”(hŒ`contribution`”h]”hŒ contribution”…”�”}”(hjP h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj$ ubhŒ property of each map in the ”…”�”}”(hj$ h²hh³Nh´Nubj6)�”}”(hŒ`cooling-maps`”h]”hŒ cooling-maps”…”�”}”(hjb h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj$ ubhŒ node.”…”�”}”(hj$ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´Mhj h²hubh¶)�”}”(hhh]”(h»)�”}”(hŒ+Limitations of the power allocator governor”h]”hŒ+Limitations of the power allocator governor”…”�”}”(hj} h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjz h²hh³hÊh´MubhÝ)�”}”(hXæThe power allocator governor's PID controller works best if there is a periodic tick. If you have a driver that calls `thermal_zone_device_update()` (or anything that ends up calling the governor's `throttle()` function) repetitively, the governor response won't be very good. Note that this is not particular to this governor, step-wise will also misbehave if you call its throttle() faster than the normal thermal framework tick (due to interrupts for example) as it will overreact.”h]”(hŒyThe power allocator governor’s PID controller works best if there is a periodic tick. If you have a driver that calls ”…”�”}”(hj‹ h²hh³Nh´Nubj6)�”}”(hŒ`thermal_zone_device_update()`”h]”hŒthermal_zone_device_update()”…”�”}”(hj“ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj‹ ubhŒ4 (or anything that ends up calling the governor’s ”…”�”}”(hj‹ h²hh³Nh´Nubj6)�”}”(hŒ `throttle()`”h]”hŒ throttle()”…”�”}”(hj¥ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1j5hj‹ ubhX function) repetitively, the governor response won’t be very good. Note that this is not particular to this governor, step-wise will also misbehave if you call its throttle() faster than the normal thermal framework tick (due to interrupts for example) as it will overreact.”…”�”}”(hj‹ h²hh³Nh´Nubeh}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´M hjz h²hubeh}”(h]”Œ+limitations-of-the-power-allocator-governor”ah ]”h"]”Œ+limitations of the power allocator governor”ah$]”h&]”uh1hµhj h²hh³hÊh´Mubh¶)�”}”(hhh]”(h»)�”}”(hŒEnergy Model requirements”h]”hŒEnergy Model requirements”…”�”}”(hjÈ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÅ h²hh³hÊh´MubhÝ)�”}”(hŒøAnother important thing is the consistent scale of the power values provided by the cooling devices. All of the cooling devices in a single thermal zone should have power values reported either in milli-Watts or scaled to the same 'abstract scale'.”h]”hŒüAnother important thing is the consistent scale of the power values provided by the cooling devices. All of the cooling devices in a single thermal zone should have power values reported either in milli-Watts or scaled to the same ‘abstract scale’.”…”�”}”(hjÖ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜh³hÊh´MhjÅ h²hubeh}”(h]”Œenergy-model-requirements”ah ]”h"]”Œenergy model requirements”ah$]”h&]”uh1hµhj h²hh³hÊh´Mubeh}”(h]”Œcooling-device-weights”ah ]”h"]”Œcooling device weights”ah$]”h&]”uh1hµhh·h²hh³hÊh´Köubeh}”(h]”Œ!power-allocator-governor-tunables”ah ]”h"]”Œ!power allocator governor tunables”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)�”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(jù jö j3j0jjjðjíjTjQjÑjÎj jÿjúj÷jñ jî j j¿ jé jæ uŒ nametypes”}”(jù ‰j3‰j‰jð‰jT‰jщj ‰jú‰jñ ‰j ‰jé ‰uh}”(jö h·j0hËjj6jíjjQjójÎjWjÿjÔj÷jjî j j¿ jz jæ jÅ uŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”(hŒsystem_message”“”)�”}”(hhh]”hÝ)�”}”(hŒ:Enumerated list start value not ordinal-1: "2" (ordinal 2)”h]”hŒ>Enumerated list start value not ordinal-1: “2â€� (ordinal 2)”…”�”}”(hj† h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜhjƒ ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”ŒINFO”Œsource”hÊŒline”Kuh1j� hjh²hh³hÊh´KÍubj‚ )�”}”(hhh]”hÝ)�”}”(hŒ:Enumerated list start value not ordinal-1: "3" (ordinal 3)”h]”hŒ>Enumerated list start value not ordinal-1: “3â€� (ordinal 3)”…”�”}”(hj¢ h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hÜhjŸ ubah}”(h]”h ]”h"]”h$]”h&]”Œlevel”KŒtype”jœ Œsource”hÊŒline”Kuh1j� hjh²hh³hÊh´KáubeŒtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.