This source file includes following definitions.
- mul_frac
- div_frac
- estimate_sustainable_power
- estimate_pid_constants
- pid_controller
- divvy_up_power
- allocate_power
- get_governor_trips
- reset_pid_controller
- allow_maximum_power
- power_allocator_bind
- power_allocator_unbind
- power_allocator_throttle
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #define pr_fmt(fmt) "Power allocator: " fmt
17
18 #include <linux/rculist.h>
19 #include <linux/slab.h>
20 #include <linux/thermal.h>
21
22 #define CREATE_TRACE_POINTS
23 #include <trace/events/thermal_power_allocator.h>
24
25 #include "thermal_core.h"
26
27 #define INVALID_TRIP -1
28
29 #define FRAC_BITS 10
30 #define int_to_frac(x) ((x) << FRAC_BITS)
31 #define frac_to_int(x) ((x) >> FRAC_BITS)
32
33
34
35
36
37
38
39
40
41 static inline s64 mul_frac(s64 x, s64 y)
42 {
43 return (x * y) >> FRAC_BITS;
44 }
45
46
47
48
49
50
51
52
53
54 static inline s64 div_frac(s64 x, s64 y)
55 {
56 return div_s64(x << FRAC_BITS, y);
57 }
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74 struct power_allocator_params {
75 bool allocated_tzp;
76 s64 err_integral;
77 s32 prev_err;
78 int trip_switch_on;
79 int trip_max_desired_temperature;
80 };
81
82
83
84
85
86
87
88
89
90
91
92
93 static u32 estimate_sustainable_power(struct thermal_zone_device *tz)
94 {
95 u32 sustainable_power = 0;
96 struct thermal_instance *instance;
97 struct power_allocator_params *params = tz->governor_data;
98
99 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
100 struct thermal_cooling_device *cdev = instance->cdev;
101 u32 min_power;
102
103 if (instance->trip != params->trip_max_desired_temperature)
104 continue;
105
106 if (power_actor_get_min_power(cdev, tz, &min_power))
107 continue;
108
109 sustainable_power += min_power;
110 }
111
112 return sustainable_power;
113 }
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 static void estimate_pid_constants(struct thermal_zone_device *tz,
135 u32 sustainable_power, int trip_switch_on,
136 int control_temp, bool force)
137 {
138 int ret;
139 int switch_on_temp;
140 u32 temperature_threshold;
141
142 ret = tz->ops->get_trip_temp(tz, trip_switch_on, &switch_on_temp);
143 if (ret)
144 switch_on_temp = 0;
145
146 temperature_threshold = control_temp - switch_on_temp;
147
148
149
150
151
152
153
154
155 if (!temperature_threshold)
156 return;
157
158 if (!tz->tzp->k_po || force)
159 tz->tzp->k_po = int_to_frac(sustainable_power) /
160 temperature_threshold;
161
162 if (!tz->tzp->k_pu || force)
163 tz->tzp->k_pu = int_to_frac(2 * sustainable_power) /
164 temperature_threshold;
165
166 if (!tz->tzp->k_i || force)
167 tz->tzp->k_i = int_to_frac(10) / 1000;
168
169
170
171
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 static u32 pid_controller(struct thermal_zone_device *tz,
193 int control_temp,
194 u32 max_allocatable_power)
195 {
196 s64 p, i, d, power_range;
197 s32 err, max_power_frac;
198 u32 sustainable_power;
199 struct power_allocator_params *params = tz->governor_data;
200
201 max_power_frac = int_to_frac(max_allocatable_power);
202
203 if (tz->tzp->sustainable_power) {
204 sustainable_power = tz->tzp->sustainable_power;
205 } else {
206 sustainable_power = estimate_sustainable_power(tz);
207 estimate_pid_constants(tz, sustainable_power,
208 params->trip_switch_on, control_temp,
209 true);
210 }
211
212 err = control_temp - tz->temperature;
213 err = int_to_frac(err);
214
215
216 p = mul_frac(err < 0 ? tz->tzp->k_po : tz->tzp->k_pu, err);
217
218
219
220
221
222
223
224 i = mul_frac(tz->tzp->k_i, params->err_integral);
225
226 if (err < int_to_frac(tz->tzp->integral_cutoff)) {
227 s64 i_next = i + mul_frac(tz->tzp->k_i, err);
228
229 if (abs(i_next) < max_power_frac) {
230 i = i_next;
231 params->err_integral += err;
232 }
233 }
234
235
236
237
238
239
240
241
242 d = mul_frac(tz->tzp->k_d, err - params->prev_err);
243 d = div_frac(d, tz->passive_delay);
244 params->prev_err = err;
245
246 power_range = p + i + d;
247
248
249 power_range = sustainable_power + frac_to_int(power_range);
250
251 power_range = clamp(power_range, (s64)0, (s64)max_allocatable_power);
252
253 trace_thermal_power_allocator_pid(tz, frac_to_int(err),
254 frac_to_int(params->err_integral),
255 frac_to_int(p), frac_to_int(i),
256 frac_to_int(d), power_range);
257
258 return power_range;
259 }
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors,
289 u32 total_req_power, u32 power_range,
290 u32 *granted_power, u32 *extra_actor_power)
291 {
292 u32 extra_power, capped_extra_power;
293 int i;
294
295
296
297
298 if (!total_req_power)
299 total_req_power = 1;
300
301 capped_extra_power = 0;
302 extra_power = 0;
303 for (i = 0; i < num_actors; i++) {
304 u64 req_range = (u64)req_power[i] * power_range;
305
306 granted_power[i] = DIV_ROUND_CLOSEST_ULL(req_range,
307 total_req_power);
308
309 if (granted_power[i] > max_power[i]) {
310 extra_power += granted_power[i] - max_power[i];
311 granted_power[i] = max_power[i];
312 }
313
314 extra_actor_power[i] = max_power[i] - granted_power[i];
315 capped_extra_power += extra_actor_power[i];
316 }
317
318 if (!extra_power)
319 return;
320
321
322
323
324
325 extra_power = min(extra_power, capped_extra_power);
326 if (capped_extra_power > 0)
327 for (i = 0; i < num_actors; i++)
328 granted_power[i] += (extra_actor_power[i] *
329 extra_power) / capped_extra_power;
330 }
331
332 static int allocate_power(struct thermal_zone_device *tz,
333 int control_temp)
334 {
335 struct thermal_instance *instance;
336 struct power_allocator_params *params = tz->governor_data;
337 u32 *req_power, *max_power, *granted_power, *extra_actor_power;
338 u32 *weighted_req_power;
339 u32 total_req_power, max_allocatable_power, total_weighted_req_power;
340 u32 total_granted_power, power_range;
341 int i, num_actors, total_weight, ret = 0;
342 int trip_max_desired_temperature = params->trip_max_desired_temperature;
343
344 mutex_lock(&tz->lock);
345
346 num_actors = 0;
347 total_weight = 0;
348 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
349 if ((instance->trip == trip_max_desired_temperature) &&
350 cdev_is_power_actor(instance->cdev)) {
351 num_actors++;
352 total_weight += instance->weight;
353 }
354 }
355
356 if (!num_actors) {
357 ret = -ENODEV;
358 goto unlock;
359 }
360
361
362
363
364
365
366
367
368 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*max_power));
369 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*granted_power));
370 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*extra_actor_power));
371 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*weighted_req_power));
372 req_power = kcalloc(num_actors * 5, sizeof(*req_power), GFP_KERNEL);
373 if (!req_power) {
374 ret = -ENOMEM;
375 goto unlock;
376 }
377
378 max_power = &req_power[num_actors];
379 granted_power = &req_power[2 * num_actors];
380 extra_actor_power = &req_power[3 * num_actors];
381 weighted_req_power = &req_power[4 * num_actors];
382
383 i = 0;
384 total_weighted_req_power = 0;
385 total_req_power = 0;
386 max_allocatable_power = 0;
387
388 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
389 int weight;
390 struct thermal_cooling_device *cdev = instance->cdev;
391
392 if (instance->trip != trip_max_desired_temperature)
393 continue;
394
395 if (!cdev_is_power_actor(cdev))
396 continue;
397
398 if (cdev->ops->get_requested_power(cdev, tz, &req_power[i]))
399 continue;
400
401 if (!total_weight)
402 weight = 1 << FRAC_BITS;
403 else
404 weight = instance->weight;
405
406 weighted_req_power[i] = frac_to_int(weight * req_power[i]);
407
408 if (power_actor_get_max_power(cdev, tz, &max_power[i]))
409 continue;
410
411 total_req_power += req_power[i];
412 max_allocatable_power += max_power[i];
413 total_weighted_req_power += weighted_req_power[i];
414
415 i++;
416 }
417
418 power_range = pid_controller(tz, control_temp, max_allocatable_power);
419
420 divvy_up_power(weighted_req_power, max_power, num_actors,
421 total_weighted_req_power, power_range, granted_power,
422 extra_actor_power);
423
424 total_granted_power = 0;
425 i = 0;
426 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
427 if (instance->trip != trip_max_desired_temperature)
428 continue;
429
430 if (!cdev_is_power_actor(instance->cdev))
431 continue;
432
433 power_actor_set_power(instance->cdev, instance,
434 granted_power[i]);
435 total_granted_power += granted_power[i];
436
437 i++;
438 }
439
440 trace_thermal_power_allocator(tz, req_power, total_req_power,
441 granted_power, total_granted_power,
442 num_actors, power_range,
443 max_allocatable_power, tz->temperature,
444 control_temp - tz->temperature);
445
446 kfree(req_power);
447 unlock:
448 mutex_unlock(&tz->lock);
449
450 return ret;
451 }
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468 static void get_governor_trips(struct thermal_zone_device *tz,
469 struct power_allocator_params *params)
470 {
471 int i, last_active, last_passive;
472 bool found_first_passive;
473
474 found_first_passive = false;
475 last_active = INVALID_TRIP;
476 last_passive = INVALID_TRIP;
477
478 for (i = 0; i < tz->trips; i++) {
479 enum thermal_trip_type type;
480 int ret;
481
482 ret = tz->ops->get_trip_type(tz, i, &type);
483 if (ret) {
484 dev_warn(&tz->device,
485 "Failed to get trip point %d type: %d\n", i,
486 ret);
487 continue;
488 }
489
490 if (type == THERMAL_TRIP_PASSIVE) {
491 if (!found_first_passive) {
492 params->trip_switch_on = i;
493 found_first_passive = true;
494 } else {
495 last_passive = i;
496 }
497 } else if (type == THERMAL_TRIP_ACTIVE) {
498 last_active = i;
499 } else {
500 break;
501 }
502 }
503
504 if (last_passive != INVALID_TRIP) {
505 params->trip_max_desired_temperature = last_passive;
506 } else if (found_first_passive) {
507 params->trip_max_desired_temperature = params->trip_switch_on;
508 params->trip_switch_on = INVALID_TRIP;
509 } else {
510 params->trip_switch_on = INVALID_TRIP;
511 params->trip_max_desired_temperature = last_active;
512 }
513 }
514
515 static void reset_pid_controller(struct power_allocator_params *params)
516 {
517 params->err_integral = 0;
518 params->prev_err = 0;
519 }
520
521 static void allow_maximum_power(struct thermal_zone_device *tz)
522 {
523 struct thermal_instance *instance;
524 struct power_allocator_params *params = tz->governor_data;
525
526 mutex_lock(&tz->lock);
527 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
528 if ((instance->trip != params->trip_max_desired_temperature) ||
529 (!cdev_is_power_actor(instance->cdev)))
530 continue;
531
532 instance->target = 0;
533 mutex_lock(&instance->cdev->lock);
534 instance->cdev->updated = false;
535 mutex_unlock(&instance->cdev->lock);
536 thermal_cdev_update(instance->cdev);
537 }
538 mutex_unlock(&tz->lock);
539 }
540
541
542
543
544
545
546
547
548
549
550 static int power_allocator_bind(struct thermal_zone_device *tz)
551 {
552 int ret;
553 struct power_allocator_params *params;
554 int control_temp;
555
556 params = kzalloc(sizeof(*params), GFP_KERNEL);
557 if (!params)
558 return -ENOMEM;
559
560 if (!tz->tzp) {
561 tz->tzp = kzalloc(sizeof(*tz->tzp), GFP_KERNEL);
562 if (!tz->tzp) {
563 ret = -ENOMEM;
564 goto free_params;
565 }
566
567 params->allocated_tzp = true;
568 }
569
570 if (!tz->tzp->sustainable_power)
571 dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n");
572
573 get_governor_trips(tz, params);
574
575 if (tz->trips > 0) {
576 ret = tz->ops->get_trip_temp(tz,
577 params->trip_max_desired_temperature,
578 &control_temp);
579 if (!ret)
580 estimate_pid_constants(tz, tz->tzp->sustainable_power,
581 params->trip_switch_on,
582 control_temp, false);
583 }
584
585 reset_pid_controller(params);
586
587 tz->governor_data = params;
588
589 return 0;
590
591 free_params:
592 kfree(params);
593
594 return ret;
595 }
596
597 static void power_allocator_unbind(struct thermal_zone_device *tz)
598 {
599 struct power_allocator_params *params = tz->governor_data;
600
601 dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id);
602
603 if (params->allocated_tzp) {
604 kfree(tz->tzp);
605 tz->tzp = NULL;
606 }
607
608 kfree(tz->governor_data);
609 tz->governor_data = NULL;
610 }
611
612 static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
613 {
614 int ret;
615 int switch_on_temp, control_temp;
616 struct power_allocator_params *params = tz->governor_data;
617
618
619
620
621
622 if (trip != params->trip_max_desired_temperature)
623 return 0;
624
625 ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
626 &switch_on_temp);
627 if (!ret && (tz->temperature < switch_on_temp)) {
628 tz->passive = 0;
629 reset_pid_controller(params);
630 allow_maximum_power(tz);
631 return 0;
632 }
633
634 tz->passive = 1;
635
636 ret = tz->ops->get_trip_temp(tz, params->trip_max_desired_temperature,
637 &control_temp);
638 if (ret) {
639 dev_warn(&tz->device,
640 "Failed to get the maximum desired temperature: %d\n",
641 ret);
642 return ret;
643 }
644
645 return allocate_power(tz, control_temp);
646 }
647
648 static struct thermal_governor thermal_gov_power_allocator = {
649 .name = "power_allocator",
650 .bind_to_tz = power_allocator_bind,
651 .unbind_from_tz = power_allocator_unbind,
652 .throttle = power_allocator_throttle,
653 };
654 THERMAL_GOVERNOR_DECLARE(thermal_gov_power_allocator);