The patch adds simple implementation of control algorithm based on PI with additional decaying for integral.
Signed-off-by: Lukasz Luba l.luba@partner.samsung.com --- kernel/sched/power.c | 26 ++++++++++++++++++++++++-- kernel/sched/power.h | 2 ++ 2 files changed, 26 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/power.c b/kernel/sched/power.c index f74c59e83d4f..20f5618d8f2b 100644 --- a/kernel/sched/power.c +++ b/kernel/sched/power.c @@ -475,6 +475,9 @@ struct trip_ctrl_alg { int switch_on_temp; int desired_id; int desired_temp; + int k_p; + int k_i; + s64 integral; };
struct _thermal_zone { @@ -532,16 +535,33 @@ static u32 calc_power_budget(struct _thermal_zone *zone) { s64 temp_diff; int desired_temp = zone->trip_ctrl_alg.desired_temp; - s64 power_budget; + s64 power_budget, p, i; + s64 decay; + int k_i = zone->trip_ctrl_alg.k_i; struct thermal_zone_device *tz = zone->tz;
/* temperature is represented in milidegress */ temp_diff = desired_temp - tz->temperature;
- power_budget = temp_diff; + p = temp_diff * zone->trip_ctrl_alg.k_p; + + i = zone->trip_ctrl_alg.integral * k_i; + + if (temp_diff < 0) { + s64 i_0 = i + k_i * temp_diff; + + zone->trip_ctrl_alg.integral += temp_diff; + } + + power_budget = p + i; + power_budget >>= 10;
power_budget = max(0LL, power_budget);
+ /* decay of 1/8 (~12.5%), after a while will reach 0 */ + decay = zone->trip_ctrl_alg.integral >> 3; + zone->trip_ctrl_alg.integral -= decay; + return power_budget; }
@@ -764,6 +784,8 @@ static int sched_power_setup_trips(struct _thermal_zone *zone)
zone->trip_ctrl_alg.switch_on_id = -EINVAL; zone->trip_ctrl_alg.desired_id = -EINVAL; + zone->trip_ctrl_alg.k_p = DEFAULT_K_P; + zone->trip_ctrl_alg.k_i = DEFAULT_K_I;
for (i = 0; i < tz->trips; i++) { ret = tz->ops->get_trip_ctrl_alg_flag(tz, i, diff --git a/kernel/sched/power.h b/kernel/sched/power.h index 77516a6f5809..340b3924ecd7 100644 --- a/kernel/sched/power.h +++ b/kernel/sched/power.h @@ -19,6 +19,8 @@
#define MAX_WEIGHT 1024 #define DEFAULT_WEIGHT MAX_WEIGHT +#define DEFAULT_K_P 500 +#define DEFAULT_K_I 50
struct power_budget { s64 temp;