0001
0002
0003
0004
0005
0006
0007
0008
0009 #define pr_fmt(fmt) "Power allocator: " fmt
0010
0011 #include <linux/rculist.h>
0012 #include <linux/slab.h>
0013 #include <linux/thermal.h>
0014
0015 #define CREATE_TRACE_POINTS
0016 #include <trace/events/thermal_power_allocator.h>
0017
0018 #include "thermal_core.h"
0019
0020 #define INVALID_TRIP -1
0021
0022 #define FRAC_BITS 10
0023 #define int_to_frac(x) ((x) << FRAC_BITS)
0024 #define frac_to_int(x) ((x) >> FRAC_BITS)
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 static inline s64 mul_frac(s64 x, s64 y)
0035 {
0036 return (x * y) >> FRAC_BITS;
0037 }
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 static inline s64 div_frac(s64 x, s64 y)
0048 {
0049 return div_s64(x << FRAC_BITS, y);
0050 }
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 struct power_allocator_params {
0070 bool allocated_tzp;
0071 s64 err_integral;
0072 s32 prev_err;
0073 int trip_switch_on;
0074 int trip_max_desired_temperature;
0075 u32 sustainable_power;
0076 };
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087
0088
0089 static u32 estimate_sustainable_power(struct thermal_zone_device *tz)
0090 {
0091 u32 sustainable_power = 0;
0092 struct thermal_instance *instance;
0093 struct power_allocator_params *params = tz->governor_data;
0094
0095 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
0096 struct thermal_cooling_device *cdev = instance->cdev;
0097 u32 min_power;
0098
0099 if (instance->trip != params->trip_max_desired_temperature)
0100 continue;
0101
0102 if (!cdev_is_power_actor(cdev))
0103 continue;
0104
0105 if (cdev->ops->state2power(cdev, instance->upper, &min_power))
0106 continue;
0107
0108 sustainable_power += min_power;
0109 }
0110
0111 return sustainable_power;
0112 }
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124 static void estimate_pid_constants(struct thermal_zone_device *tz,
0125 u32 sustainable_power, int trip_switch_on,
0126 int control_temp)
0127 {
0128 int ret;
0129 int switch_on_temp;
0130 u32 temperature_threshold;
0131 s32 k_i;
0132
0133 ret = tz->ops->get_trip_temp(tz, trip_switch_on, &switch_on_temp);
0134 if (ret)
0135 switch_on_temp = 0;
0136
0137 temperature_threshold = control_temp - switch_on_temp;
0138
0139
0140
0141
0142
0143
0144
0145
0146 if (!temperature_threshold)
0147 return;
0148
0149 tz->tzp->k_po = int_to_frac(sustainable_power) /
0150 temperature_threshold;
0151
0152 tz->tzp->k_pu = int_to_frac(2 * sustainable_power) /
0153 temperature_threshold;
0154
0155 k_i = tz->tzp->k_pu / 10;
0156 tz->tzp->k_i = k_i > 0 ? k_i : 1;
0157
0158
0159
0160
0161
0162 }
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 static u32 get_sustainable_power(struct thermal_zone_device *tz,
0176 struct power_allocator_params *params,
0177 int control_temp)
0178 {
0179 u32 sustainable_power;
0180
0181 if (!tz->tzp->sustainable_power)
0182 sustainable_power = estimate_sustainable_power(tz);
0183 else
0184 sustainable_power = tz->tzp->sustainable_power;
0185
0186
0187 if (sustainable_power != params->sustainable_power) {
0188 estimate_pid_constants(tz, sustainable_power,
0189 params->trip_switch_on, control_temp);
0190
0191
0192 tz->tzp->sustainable_power = sustainable_power;
0193 params->sustainable_power = sustainable_power;
0194 }
0195
0196 return sustainable_power;
0197 }
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215
0216
0217 static u32 pid_controller(struct thermal_zone_device *tz,
0218 int control_temp,
0219 u32 max_allocatable_power)
0220 {
0221 s64 p, i, d, power_range;
0222 s32 err, max_power_frac;
0223 u32 sustainable_power;
0224 struct power_allocator_params *params = tz->governor_data;
0225
0226 max_power_frac = int_to_frac(max_allocatable_power);
0227
0228 sustainable_power = get_sustainable_power(tz, params, control_temp);
0229
0230 err = control_temp - tz->temperature;
0231 err = int_to_frac(err);
0232
0233
0234 p = mul_frac(err < 0 ? tz->tzp->k_po : tz->tzp->k_pu, err);
0235
0236
0237
0238
0239
0240
0241
0242 i = mul_frac(tz->tzp->k_i, params->err_integral);
0243
0244 if (err < int_to_frac(tz->tzp->integral_cutoff)) {
0245 s64 i_next = i + mul_frac(tz->tzp->k_i, err);
0246
0247 if (abs(i_next) < max_power_frac) {
0248 i = i_next;
0249 params->err_integral += err;
0250 }
0251 }
0252
0253
0254
0255
0256
0257
0258
0259
0260 d = mul_frac(tz->tzp->k_d, err - params->prev_err);
0261 d = div_frac(d, jiffies_to_msecs(tz->passive_delay_jiffies));
0262 params->prev_err = err;
0263
0264 power_range = p + i + d;
0265
0266
0267 power_range = sustainable_power + frac_to_int(power_range);
0268
0269 power_range = clamp(power_range, (s64)0, (s64)max_allocatable_power);
0270
0271 trace_thermal_power_allocator_pid(tz, frac_to_int(err),
0272 frac_to_int(params->err_integral),
0273 frac_to_int(p), frac_to_int(i),
0274 frac_to_int(d), power_range);
0275
0276 return power_range;
0277 }
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291 static int
0292 power_actor_set_power(struct thermal_cooling_device *cdev,
0293 struct thermal_instance *instance, u32 power)
0294 {
0295 unsigned long state;
0296 int ret;
0297
0298 ret = cdev->ops->power2state(cdev, power, &state);
0299 if (ret)
0300 return ret;
0301
0302 instance->target = clamp_val(state, instance->lower, instance->upper);
0303 mutex_lock(&cdev->lock);
0304 __thermal_cdev_update(cdev);
0305 mutex_unlock(&cdev->lock);
0306
0307 return 0;
0308 }
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337 static void divvy_up_power(u32 *req_power, u32 *max_power, int num_actors,
0338 u32 total_req_power, u32 power_range,
0339 u32 *granted_power, u32 *extra_actor_power)
0340 {
0341 u32 extra_power, capped_extra_power;
0342 int i;
0343
0344
0345
0346
0347 if (!total_req_power)
0348 total_req_power = 1;
0349
0350 capped_extra_power = 0;
0351 extra_power = 0;
0352 for (i = 0; i < num_actors; i++) {
0353 u64 req_range = (u64)req_power[i] * power_range;
0354
0355 granted_power[i] = DIV_ROUND_CLOSEST_ULL(req_range,
0356 total_req_power);
0357
0358 if (granted_power[i] > max_power[i]) {
0359 extra_power += granted_power[i] - max_power[i];
0360 granted_power[i] = max_power[i];
0361 }
0362
0363 extra_actor_power[i] = max_power[i] - granted_power[i];
0364 capped_extra_power += extra_actor_power[i];
0365 }
0366
0367 if (!extra_power)
0368 return;
0369
0370
0371
0372
0373
0374 extra_power = min(extra_power, capped_extra_power);
0375 if (capped_extra_power > 0)
0376 for (i = 0; i < num_actors; i++) {
0377 u64 extra_range = (u64)extra_actor_power[i] * extra_power;
0378 granted_power[i] += DIV_ROUND_CLOSEST_ULL(extra_range,
0379 capped_extra_power);
0380 }
0381 }
0382
0383 static int allocate_power(struct thermal_zone_device *tz,
0384 int control_temp)
0385 {
0386 struct thermal_instance *instance;
0387 struct power_allocator_params *params = tz->governor_data;
0388 u32 *req_power, *max_power, *granted_power, *extra_actor_power;
0389 u32 *weighted_req_power;
0390 u32 total_req_power, max_allocatable_power, total_weighted_req_power;
0391 u32 total_granted_power, power_range;
0392 int i, num_actors, total_weight, ret = 0;
0393 int trip_max_desired_temperature = params->trip_max_desired_temperature;
0394
0395 mutex_lock(&tz->lock);
0396
0397 num_actors = 0;
0398 total_weight = 0;
0399 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
0400 if ((instance->trip == trip_max_desired_temperature) &&
0401 cdev_is_power_actor(instance->cdev)) {
0402 num_actors++;
0403 total_weight += instance->weight;
0404 }
0405 }
0406
0407 if (!num_actors) {
0408 ret = -ENODEV;
0409 goto unlock;
0410 }
0411
0412
0413
0414
0415
0416
0417
0418
0419 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*max_power));
0420 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*granted_power));
0421 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*extra_actor_power));
0422 BUILD_BUG_ON(sizeof(*req_power) != sizeof(*weighted_req_power));
0423 req_power = kcalloc(num_actors * 5, sizeof(*req_power), GFP_KERNEL);
0424 if (!req_power) {
0425 ret = -ENOMEM;
0426 goto unlock;
0427 }
0428
0429 max_power = &req_power[num_actors];
0430 granted_power = &req_power[2 * num_actors];
0431 extra_actor_power = &req_power[3 * num_actors];
0432 weighted_req_power = &req_power[4 * num_actors];
0433
0434 i = 0;
0435 total_weighted_req_power = 0;
0436 total_req_power = 0;
0437 max_allocatable_power = 0;
0438
0439 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
0440 int weight;
0441 struct thermal_cooling_device *cdev = instance->cdev;
0442
0443 if (instance->trip != trip_max_desired_temperature)
0444 continue;
0445
0446 if (!cdev_is_power_actor(cdev))
0447 continue;
0448
0449 if (cdev->ops->get_requested_power(cdev, &req_power[i]))
0450 continue;
0451
0452 if (!total_weight)
0453 weight = 1 << FRAC_BITS;
0454 else
0455 weight = instance->weight;
0456
0457 weighted_req_power[i] = frac_to_int(weight * req_power[i]);
0458
0459 if (cdev->ops->state2power(cdev, instance->lower,
0460 &max_power[i]))
0461 continue;
0462
0463 total_req_power += req_power[i];
0464 max_allocatable_power += max_power[i];
0465 total_weighted_req_power += weighted_req_power[i];
0466
0467 i++;
0468 }
0469
0470 power_range = pid_controller(tz, control_temp, max_allocatable_power);
0471
0472 divvy_up_power(weighted_req_power, max_power, num_actors,
0473 total_weighted_req_power, power_range, granted_power,
0474 extra_actor_power);
0475
0476 total_granted_power = 0;
0477 i = 0;
0478 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
0479 if (instance->trip != trip_max_desired_temperature)
0480 continue;
0481
0482 if (!cdev_is_power_actor(instance->cdev))
0483 continue;
0484
0485 power_actor_set_power(instance->cdev, instance,
0486 granted_power[i]);
0487 total_granted_power += granted_power[i];
0488
0489 i++;
0490 }
0491
0492 trace_thermal_power_allocator(tz, req_power, total_req_power,
0493 granted_power, total_granted_power,
0494 num_actors, power_range,
0495 max_allocatable_power, tz->temperature,
0496 control_temp - tz->temperature);
0497
0498 kfree(req_power);
0499 unlock:
0500 mutex_unlock(&tz->lock);
0501
0502 return ret;
0503 }
0504
0505
0506
0507
0508
0509
0510
0511
0512
0513
0514
0515
0516
0517
0518
0519
0520 static void get_governor_trips(struct thermal_zone_device *tz,
0521 struct power_allocator_params *params)
0522 {
0523 int i, last_active, last_passive;
0524 bool found_first_passive;
0525
0526 found_first_passive = false;
0527 last_active = INVALID_TRIP;
0528 last_passive = INVALID_TRIP;
0529
0530 for (i = 0; i < tz->num_trips; i++) {
0531 enum thermal_trip_type type;
0532 int ret;
0533
0534 ret = tz->ops->get_trip_type(tz, i, &type);
0535 if (ret) {
0536 dev_warn(&tz->device,
0537 "Failed to get trip point %d type: %d\n", i,
0538 ret);
0539 continue;
0540 }
0541
0542 if (type == THERMAL_TRIP_PASSIVE) {
0543 if (!found_first_passive) {
0544 params->trip_switch_on = i;
0545 found_first_passive = true;
0546 } else {
0547 last_passive = i;
0548 }
0549 } else if (type == THERMAL_TRIP_ACTIVE) {
0550 last_active = i;
0551 } else {
0552 break;
0553 }
0554 }
0555
0556 if (last_passive != INVALID_TRIP) {
0557 params->trip_max_desired_temperature = last_passive;
0558 } else if (found_first_passive) {
0559 params->trip_max_desired_temperature = params->trip_switch_on;
0560 params->trip_switch_on = INVALID_TRIP;
0561 } else {
0562 params->trip_switch_on = INVALID_TRIP;
0563 params->trip_max_desired_temperature = last_active;
0564 }
0565 }
0566
0567 static void reset_pid_controller(struct power_allocator_params *params)
0568 {
0569 params->err_integral = 0;
0570 params->prev_err = 0;
0571 }
0572
0573 static void allow_maximum_power(struct thermal_zone_device *tz, bool update)
0574 {
0575 struct thermal_instance *instance;
0576 struct power_allocator_params *params = tz->governor_data;
0577 u32 req_power;
0578
0579 mutex_lock(&tz->lock);
0580 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
0581 struct thermal_cooling_device *cdev = instance->cdev;
0582
0583 if ((instance->trip != params->trip_max_desired_temperature) ||
0584 (!cdev_is_power_actor(instance->cdev)))
0585 continue;
0586
0587 instance->target = 0;
0588 mutex_lock(&instance->cdev->lock);
0589
0590
0591
0592
0593
0594 cdev->ops->get_requested_power(cdev, &req_power);
0595
0596 if (update)
0597 __thermal_cdev_update(instance->cdev);
0598
0599 mutex_unlock(&instance->cdev->lock);
0600 }
0601 mutex_unlock(&tz->lock);
0602 }
0603
0604
0605
0606
0607
0608
0609
0610
0611
0612
0613
0614
0615
0616 static int check_power_actors(struct thermal_zone_device *tz)
0617 {
0618 struct thermal_instance *instance;
0619 int ret = 0;
0620
0621 list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
0622 if (!cdev_is_power_actor(instance->cdev)) {
0623 dev_warn(&tz->device, "power_allocator: %s is not a power actor\n",
0624 instance->cdev->type);
0625 ret = -EINVAL;
0626 }
0627 }
0628
0629 return ret;
0630 }
0631
0632
0633
0634
0635
0636
0637
0638
0639
0640
0641
0642 static int power_allocator_bind(struct thermal_zone_device *tz)
0643 {
0644 int ret;
0645 struct power_allocator_params *params;
0646 int control_temp;
0647
0648 ret = check_power_actors(tz);
0649 if (ret)
0650 return ret;
0651
0652 params = kzalloc(sizeof(*params), GFP_KERNEL);
0653 if (!params)
0654 return -ENOMEM;
0655
0656 if (!tz->tzp) {
0657 tz->tzp = kzalloc(sizeof(*tz->tzp), GFP_KERNEL);
0658 if (!tz->tzp) {
0659 ret = -ENOMEM;
0660 goto free_params;
0661 }
0662
0663 params->allocated_tzp = true;
0664 }
0665
0666 if (!tz->tzp->sustainable_power)
0667 dev_warn(&tz->device, "power_allocator: sustainable_power will be estimated\n");
0668
0669 get_governor_trips(tz, params);
0670
0671 if (tz->num_trips > 0) {
0672 ret = tz->ops->get_trip_temp(tz,
0673 params->trip_max_desired_temperature,
0674 &control_temp);
0675 if (!ret)
0676 estimate_pid_constants(tz, tz->tzp->sustainable_power,
0677 params->trip_switch_on,
0678 control_temp);
0679 }
0680
0681 reset_pid_controller(params);
0682
0683 tz->governor_data = params;
0684
0685 return 0;
0686
0687 free_params:
0688 kfree(params);
0689
0690 return ret;
0691 }
0692
0693 static void power_allocator_unbind(struct thermal_zone_device *tz)
0694 {
0695 struct power_allocator_params *params = tz->governor_data;
0696
0697 dev_dbg(&tz->device, "Unbinding from thermal zone %d\n", tz->id);
0698
0699 if (params->allocated_tzp) {
0700 kfree(tz->tzp);
0701 tz->tzp = NULL;
0702 }
0703
0704 kfree(tz->governor_data);
0705 tz->governor_data = NULL;
0706 }
0707
0708 static int power_allocator_throttle(struct thermal_zone_device *tz, int trip)
0709 {
0710 int ret;
0711 int switch_on_temp, control_temp;
0712 struct power_allocator_params *params = tz->governor_data;
0713 bool update;
0714
0715
0716
0717
0718
0719 if (trip != params->trip_max_desired_temperature)
0720 return 0;
0721
0722 ret = tz->ops->get_trip_temp(tz, params->trip_switch_on,
0723 &switch_on_temp);
0724 if (!ret && (tz->temperature < switch_on_temp)) {
0725 update = (tz->last_temperature >= switch_on_temp);
0726 tz->passive = 0;
0727 reset_pid_controller(params);
0728 allow_maximum_power(tz, update);
0729 return 0;
0730 }
0731
0732 tz->passive = 1;
0733
0734 ret = tz->ops->get_trip_temp(tz, params->trip_max_desired_temperature,
0735 &control_temp);
0736 if (ret) {
0737 dev_warn(&tz->device,
0738 "Failed to get the maximum desired temperature: %d\n",
0739 ret);
0740 return ret;
0741 }
0742
0743 return allocate_power(tz, control_temp);
0744 }
0745
0746 static struct thermal_governor thermal_gov_power_allocator = {
0747 .name = "power_allocator",
0748 .bind_to_tz = power_allocator_bind,
0749 .unbind_from_tz = power_allocator_unbind,
0750 .throttle = power_allocator_throttle,
0751 };
0752 THERMAL_GOVERNOR_DECLARE(thermal_gov_power_allocator);