Commit 6b775e87 authored by Javi Merino's avatar Javi Merino Committed by Eduardo Valentin

thermal: introduce the Power Allocator governor

The power allocator governor is a thermal governor that controls system
and device power allocation to control temperature.  Conceptually, the
implementation divides the sustainable power of a thermal zone among
all the heat sources in that zone.

This governor relies on "power actors", entities that represent heat
sources.  They can report current and maximum power consumption and
can set a given maximum power consumption, usually via a cooling
device.

The governor uses a Proportional Integral Derivative (PID) controller
driven by the temperature of the thermal zone.  The output of the
controller is a power budget that is then allocated to each power
actor that can have bearing on the temperature we are trying to
control.  It decides how much power to give each cooling device based
on the performance they are requesting.  The PID controller ensures
that the total power budget does not exceed the control temperature.

Cc: Zhang Rui <rui.zhang@intel.com>
Cc: Eduardo Valentin <edubezval@gmail.com>
Signed-off-by: default avatarPunit Agrawal <punit.agrawal@arm.com>
Signed-off-by: default avatarJavi Merino <javi.merino@arm.com>
Signed-off-by: default avatarEduardo Valentin <edubezval@gmail.com>
parent c36cf071
This diff is collapsed.
...@@ -71,6 +71,14 @@ config THERMAL_DEFAULT_GOV_USER_SPACE ...@@ -71,6 +71,14 @@ config THERMAL_DEFAULT_GOV_USER_SPACE
Select this if you want to let the user space manage the Select this if you want to let the user space manage the
platform thermals. platform thermals.
config THERMAL_DEFAULT_GOV_POWER_ALLOCATOR
bool "power_allocator"
select THERMAL_GOV_POWER_ALLOCATOR
help
Select this if you want to control temperature based on
system and device power allocation. This governor can only
operate on cooling devices that implement the power API.
endchoice endchoice
config THERMAL_GOV_FAIR_SHARE config THERMAL_GOV_FAIR_SHARE
...@@ -99,6 +107,13 @@ config THERMAL_GOV_USER_SPACE ...@@ -99,6 +107,13 @@ config THERMAL_GOV_USER_SPACE
help help
Enable this to let the user space manage the platform thermals. Enable this to let the user space manage the platform thermals.
config THERMAL_GOV_POWER_ALLOCATOR
bool "Power allocator thermal governor"
select THERMAL_POWER_ACTOR
help
Enable this to manage platform thermals by dynamically
allocating and limiting power to devices.
config CPU_THERMAL config CPU_THERMAL
bool "generic cpu cooling support" bool "generic cpu cooling support"
depends on CPU_FREQ depends on CPU_FREQ
......
...@@ -14,6 +14,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o ...@@ -14,6 +14,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_FAIR_SHARE) += fair_share.o
thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o thermal_sys-$(CONFIG_THERMAL_GOV_BANG_BANG) += gov_bang_bang.o
thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += step_wise.o thermal_sys-$(CONFIG_THERMAL_GOV_STEP_WISE) += step_wise.o
thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o
thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o
# cpufreq cooling # cpufreq cooling
thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o
......
This diff is collapsed.
...@@ -1616,7 +1616,7 @@ static void remove_trip_attrs(struct thermal_zone_device *tz) ...@@ -1616,7 +1616,7 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
struct thermal_zone_device *thermal_zone_device_register(const char *type, struct thermal_zone_device *thermal_zone_device_register(const char *type,
int trips, int mask, void *devdata, int trips, int mask, void *devdata,
struct thermal_zone_device_ops *ops, struct thermal_zone_device_ops *ops,
const struct thermal_zone_params *tzp, struct thermal_zone_params *tzp,
int passive_delay, int polling_delay) int passive_delay, int polling_delay)
{ {
struct thermal_zone_device *tz; struct thermal_zone_device *tz;
...@@ -1968,7 +1968,11 @@ static int __init thermal_register_governors(void) ...@@ -1968,7 +1968,11 @@ static int __init thermal_register_governors(void)
if (result) if (result)
return result; return result;
return thermal_gov_user_space_register(); result = thermal_gov_user_space_register();
if (result)
return result;
return thermal_gov_power_allocator_register();
} }
static void thermal_unregister_governors(void) static void thermal_unregister_governors(void)
...@@ -1977,6 +1981,7 @@ static void thermal_unregister_governors(void) ...@@ -1977,6 +1981,7 @@ static void thermal_unregister_governors(void)
thermal_gov_fair_share_unregister(); thermal_gov_fair_share_unregister();
thermal_gov_bang_bang_unregister(); thermal_gov_bang_bang_unregister();
thermal_gov_user_space_unregister(); thermal_gov_user_space_unregister();
thermal_gov_power_allocator_unregister();
} }
static int __init thermal_init(void) static int __init thermal_init(void)
......
...@@ -88,6 +88,14 @@ static inline int thermal_gov_user_space_register(void) { return 0; } ...@@ -88,6 +88,14 @@ static inline int thermal_gov_user_space_register(void) { return 0; }
static inline void thermal_gov_user_space_unregister(void) {} static inline void thermal_gov_user_space_unregister(void) {}
#endif /* CONFIG_THERMAL_GOV_USER_SPACE */ #endif /* CONFIG_THERMAL_GOV_USER_SPACE */
#ifdef CONFIG_THERMAL_GOV_POWER_ALLOCATOR
int thermal_gov_power_allocator_register(void);
void thermal_gov_power_allocator_unregister(void);
#else
static inline int thermal_gov_power_allocator_register(void) { return 0; }
static inline void thermal_gov_power_allocator_unregister(void) {}
#endif /* CONFIG_THERMAL_GOV_POWER_ALLOCATOR */
/* device tree support */ /* device tree support */
#ifdef CONFIG_THERMAL_OF #ifdef CONFIG_THERMAL_OF
int of_parse_thermal_zones(void); int of_parse_thermal_zones(void);
......
...@@ -59,6 +59,8 @@ ...@@ -59,6 +59,8 @@
#define DEFAULT_THERMAL_GOVERNOR "fair_share" #define DEFAULT_THERMAL_GOVERNOR "fair_share"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE) #elif defined(CONFIG_THERMAL_DEFAULT_GOV_USER_SPACE)
#define DEFAULT_THERMAL_GOVERNOR "user_space" #define DEFAULT_THERMAL_GOVERNOR "user_space"
#elif defined(CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR)
#define DEFAULT_THERMAL_GOVERNOR "power_allocator"
#endif #endif
struct thermal_zone_device; struct thermal_zone_device;
...@@ -154,8 +156,7 @@ struct thermal_attr { ...@@ -154,8 +156,7 @@ struct thermal_attr {
* @devdata: private pointer for device private data * @devdata: private pointer for device private data
* @trips: number of trip points the thermal zone supports * @trips: number of trip points the thermal zone supports
* @passive_delay: number of milliseconds to wait between polls when * @passive_delay: number of milliseconds to wait between polls when
* performing passive cooling. Currenty only used by the * performing passive cooling.
* step-wise governor
* @polling_delay: number of milliseconds to wait between polls when * @polling_delay: number of milliseconds to wait between polls when
* checking whether trip points have been crossed (0 for * checking whether trip points have been crossed (0 for
* interrupt driven systems) * interrupt driven systems)
...@@ -165,7 +166,6 @@ struct thermal_attr { ...@@ -165,7 +166,6 @@ struct thermal_attr {
* @last_temperature: previous temperature read * @last_temperature: previous temperature read
* @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION * @emul_temperature: emulated temperature when using CONFIG_THERMAL_EMULATION
* @passive: 1 if you've crossed a passive trip point, 0 otherwise. * @passive: 1 if you've crossed a passive trip point, 0 otherwise.
* Currenty only used by the step-wise governor.
* @forced_passive: If > 0, temperature at which to switch on all ACPI * @forced_passive: If > 0, temperature at which to switch on all ACPI
* processor cooling devices. Currently only used by the * processor cooling devices. Currently only used by the
* step-wise governor. * step-wise governor.
...@@ -197,7 +197,7 @@ struct thermal_zone_device { ...@@ -197,7 +197,7 @@ struct thermal_zone_device {
int passive; int passive;
unsigned int forced_passive; unsigned int forced_passive;
struct thermal_zone_device_ops *ops; struct thermal_zone_device_ops *ops;
const struct thermal_zone_params *tzp; struct thermal_zone_params *tzp;
struct thermal_governor *governor; struct thermal_governor *governor;
void *governor_data; void *governor_data;
struct list_head thermal_instances; struct list_head thermal_instances;
...@@ -275,6 +275,33 @@ struct thermal_zone_params { ...@@ -275,6 +275,33 @@ struct thermal_zone_params {
int num_tbps; /* Number of tbp entries */ int num_tbps; /* Number of tbp entries */
struct thermal_bind_params *tbp; struct thermal_bind_params *tbp;
/*
* Sustainable power (heat) that this thermal zone can dissipate in
* mW
*/
u32 sustainable_power;
/*
* Proportional parameter of the PID controller when
* overshooting (i.e., when temperature is below the target)
*/
s32 k_po;
/*
* Proportional parameter of the PID controller when
* undershooting
*/
s32 k_pu;
/* Integral parameter of the PID controller */
s32 k_i;
/* Derivative parameter of the PID controller */
s32 k_d;
/* threshold below which the error is no longer accumulated */
s32 integral_cutoff;
}; };
struct thermal_genl_event { struct thermal_genl_event {
...@@ -350,7 +377,7 @@ int power_actor_set_power(struct thermal_cooling_device *, ...@@ -350,7 +377,7 @@ int power_actor_set_power(struct thermal_cooling_device *,
struct thermal_instance *, u32); struct thermal_instance *, u32);
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
void *, struct thermal_zone_device_ops *, void *, struct thermal_zone_device_ops *,
const struct thermal_zone_params *, int, int); struct thermal_zone_params *, int, int);
void thermal_zone_device_unregister(struct thermal_zone_device *); void thermal_zone_device_unregister(struct thermal_zone_device *);
int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment