• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <aidl/android/hardware/thermal/Temperature.h>
20 
21 #include <queue>
22 #include <set>
23 #include <shared_mutex>
24 #include <string>
25 #include <unordered_map>
26 #include <unordered_set>
27 
28 #include "power_files.h"
29 #include "thermal_info.h"
30 #include "thermal_stats_helper.h"
31 
32 namespace aidl {
33 namespace android {
34 namespace hardware {
35 namespace thermal {
36 namespace implementation {
37 
38 struct ThermalThrottlingStatus {
39     std::unordered_map<std::string, int> pid_power_budget_map;
40     std::unordered_map<std::string, int> pid_cdev_request_map;
41     std::unordered_map<std::string, int> hardlimit_cdev_request_map;
42     std::unordered_map<std::string, int> throttling_release_map;
43     std::unordered_map<std::string, int> cdev_status_map;
44     float prev_err;
45     float i_budget;
46     float prev_target;
47     float prev_power_budget;
48     float budget_transient;
49     int tran_cycle;
50     std::string profile;
51 };
52 
53 // Return the control temp target of PID algorithm
54 size_t getTargetStateOfPID(const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity);
55 
56 // A helper class for conducting thermal throttling
57 class ThermalThrottling {
58   public:
59     ThermalThrottling() = default;
60     ~ThermalThrottling() = default;
61     // Disallow copy and assign.
62     ThermalThrottling(const ThermalThrottling &) = delete;
63     void operator=(const ThermalThrottling &) = delete;
64 
65     // Check if the thermal throttling profile need to be switched
66     void parseProfileProperty(std::string_view sensor_name, const SensorInfo &sensor_info);
67     // Clear throttling data
68     void clearThrottlingData(std::string_view sensor_name, const SensorInfo &sensor_info);
69     // Register map for throttling algo
70     bool registerThermalThrottling(
71             std::string_view sensor_name, const std::shared_ptr<ThrottlingInfo> &throttling_info,
72             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map);
73     // Register map for throttling release algo
74     bool registerThrottlingReleaseToWatch(std::string_view sensor_name, std::string_view cdev_name,
75                                           const BindedCdevInfo &binded_cdev_info);
76     // Get throttling status map
GetThermalThrottlingStatusMap()77     const std::unordered_map<std::string, ThermalThrottlingStatus> &GetThermalThrottlingStatusMap()
78             const {
79         std::shared_lock<std::shared_mutex> _lock(thermal_throttling_status_map_mutex_);
80         return thermal_throttling_status_map_;
81     }
82     // Update thermal throttling request for the specific sensor
83     void thermalThrottlingUpdate(
84             const Temperature &temp, const SensorInfo &sensor_info,
85             const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms,
86             const std::unordered_map<std::string, PowerStatus> &power_status_map,
87             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map);
88 
89     // Compute the throttling target from all the sensors' request
90     void computeCoolingDevicesRequest(std::string_view sensor_name, const SensorInfo &sensor_info,
91                                       const ThrottlingSeverity curr_severity,
92                                       std::vector<std::string> *cooling_devices_to_update,
93                                       ThermalStatsHelper *thermal_stats_helper);
94     // Get the aggregated (from all sensor) max request for a cooling device
95     bool getCdevMaxRequest(std::string_view cdev_name, int *max_state);
96 
97   private:
98     // PID algo - get the total power budget
99     float updatePowerBudget(const Temperature &temp, const SensorInfo &sensor_info,
100                             std::chrono::milliseconds time_elapsed_ms,
101                             ThrottlingSeverity curr_severity);
102 
103     // PID algo - return the power number from excluded power rail list
104     float computeExcludedPower(const SensorInfo &sensor_info,
105                                const ThrottlingSeverity curr_severity,
106                                const std::unordered_map<std::string, PowerStatus> &power_status_map,
107                                std::string *log_buf, std::string_view sensor_name);
108 
109     // PID algo - allocate the power to target CDEV according to the ODPM
110     bool allocatePowerToCdev(
111             const Temperature &temp, const SensorInfo &sensor_info,
112             const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms,
113             const std::unordered_map<std::string, PowerStatus> &power_status_map,
114             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map);
115     // PID algo - map the target throttling state according to the power budget
116     void updateCdevRequestByPower(
117             std::string sensor_name,
118             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map);
119     // Hard limit algo - assign the throttling state according to the severity
120     void updateCdevRequestBySeverity(std::string_view sensor_name, const SensorInfo &sensor_info,
121                                      ThrottlingSeverity curr_severity);
122     // Throttling release algo - decide release step according to the predefined power threshold,
123     // return false if the throttling release is not registered in thermal config
124     bool throttlingReleaseUpdate(
125             std::string_view sensor_name,
126             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map,
127             const std::unordered_map<std::string, PowerStatus> &power_status_map,
128             const ThrottlingSeverity severity, const SensorInfo &sensor_info);
129     // Update the cooling device request set for new request and notify the caller if there is
130     // change in max_request for the cooling device.
131     bool updateCdevMaxRequestAndNotifyIfChange(std::string_view cdev_name, int cur_request,
132                                                int new_request);
133     mutable std::shared_mutex thermal_throttling_status_map_mutex_;
134     // Thermal throttling status from each sensor
135     std::unordered_map<std::string, ThermalThrottlingStatus> thermal_throttling_status_map_;
136     std::shared_mutex cdev_all_request_map_mutex_;
137     // Set of all request for a cooling device from each sensor
138     std::unordered_map<std::string, std::multiset<int, std::greater<int>>> cdev_all_request_map_;
139 };
140 
141 }  // namespace implementation
142 }  // namespace thermal
143 }  // namespace hardware
144 }  // namespace android
145 }  // namespace aidl
146