• 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 <functional>
22 #include <queue>
23 #include <set>
24 #include <shared_mutex>
25 #include <string>
26 #include <unordered_map>
27 #include <unordered_set>
28 
29 #include "power_files.h"
30 #include "thermal_info.h"
31 #include "thermal_stats_helper.h"
32 
33 namespace aidl {
34 namespace android {
35 namespace hardware {
36 namespace thermal {
37 namespace implementation {
38 
39 struct ThermalThrottlingStatus {
40     std::unordered_map<std::string, int> pid_power_budget_map;
41     std::unordered_map<std::string, int> pid_cdev_request_map;
42     std::unordered_map<std::string, int> hardlimit_cdev_request_map;
43     std::unordered_map<std::string, int> throttling_release_map;
44     std::unordered_map<std::string, int> cdev_status_map;
45     float prev_err;
46     float i_budget;
47     float prev_target;
48     float prev_power_budget;
49     float budget_transient;
50     int tran_cycle;
51     std::string profile;
52 };
53 
54 // Return the control temp target of PID algorithm
55 size_t getTargetStateOfPID(const SensorInfo &sensor_info, const ThrottlingSeverity curr_severity);
56 
57 // A helper class for conducting thermal throttling
58 class ThermalThrottling {
59   public:
60     ThermalThrottling() = default;
61     ~ThermalThrottling() = default;
62     // Disallow copy and assign.
63     ThermalThrottling(const ThermalThrottling &) = delete;
64     void operator=(const ThermalThrottling &) = delete;
65 
66     // Clear throttling data
67     void clearThrottlingData(std::string_view sensor_name);
68     // Register map for throttling algo
69     bool registerThermalThrottling(
70             std::string_view sensor_name, const std::shared_ptr<ThrottlingInfo> &throttling_info,
71             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map);
72     // Get throttling status map
GetThermalThrottlingStatusMap()73     const std::unordered_map<std::string, ThermalThrottlingStatus> &GetThermalThrottlingStatusMap()
74             const {
75         std::shared_lock<std::shared_mutex> _lock(thermal_throttling_status_map_mutex_);
76         return thermal_throttling_status_map_;
77     }
78     // Update thermal throttling request for the specific sensor
79     void thermalThrottlingUpdate(
80             const Temperature &temp, const SensorInfo &sensor_info,
81             const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms,
82             const std::unordered_map<std::string, PowerStatus> &power_status_map,
83             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map,
84             const bool max_throttling = false,
85             const std::vector<float> &sensor_predictions = std::vector<float>{});
86 
87     // Compute the throttling target from all the sensors' request
88     void computeCoolingDevicesRequest(std::string_view sensor_name, const SensorInfo &sensor_info,
89                                       const ThrottlingSeverity curr_severity,
90                                       std::vector<std::string> *cooling_devices_to_update,
91                                       ThermalStatsHelper *thermal_stats_helper);
92     // Get the aggregated (from all sensor) max request for a cooling device
93     bool getCdevMaxRequest(std::string_view cdev_name, int *max_state);
94 
95   private:
96     // Check if the thermal throttling profile need to be switched
97     void parseProfileProperty(std::string_view sensor_name, const SensorInfo &sensor_info);
98     // PID algo - get the total power budget
99     float updatePowerBudget(
100             const Temperature &temp, const SensorInfo &sensor_info,
101             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map,
102             std::chrono::milliseconds time_elapsed_ms, ThrottlingSeverity curr_severity,
103             const bool max_throttling,
104             const std::vector<float> &sensor_predictions = std::vector<float>{});
105 
106     // PID algo - return the power number from excluded power rail list
107     float computeExcludedPower(const SensorInfo &sensor_info,
108                                const ThrottlingSeverity curr_severity,
109                                const std::unordered_map<std::string, PowerStatus> &power_status_map,
110                                std::string *log_buf, std::string_view sensor_name);
111 
112     // PID algo - allocate the power to target CDEV according to the ODPM
113     bool allocatePowerToCdev(
114             const Temperature &temp, const SensorInfo &sensor_info,
115             const ThrottlingSeverity curr_severity, const std::chrono::milliseconds time_elapsed_ms,
116             const std::unordered_map<std::string, PowerStatus> &power_status_map,
117             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map,
118             const bool max_throttling, const std::vector<float> &sensor_predictions);
119     // PID algo - map the target throttling state according to the power budget
120     void updateCdevRequestByPower(
121             std::string sensor_name,
122             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map);
123     // Hard limit algo - assign the throttling state according to the severity
124     void updateCdevRequestBySeverity(std::string_view sensor_name, const SensorInfo &sensor_info,
125                                      ThrottlingSeverity curr_severity);
126     // Throttling release algo - decide release step according to the predefined power threshold,
127     // return false if the throttling release is not registered in thermal config
128     bool throttlingReleaseUpdate(
129             std::string_view sensor_name,
130             const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map,
131             const std::unordered_map<std::string, PowerStatus> &power_status_map,
132             const ThrottlingSeverity severity, const SensorInfo &sensor_info);
133     // Update the cooling device request set for new request and notify the caller if there is
134     // change in max_request for the cooling device.
135     bool updateCdevMaxRequestAndNotifyIfChange(std::string_view cdev_name, int cur_request,
136                                                int new_request);
137     mutable std::shared_mutex thermal_throttling_status_map_mutex_;
138     // Thermal throttling status from each sensor
139     std::unordered_map<std::string, ThermalThrottlingStatus> thermal_throttling_status_map_;
140     std::shared_mutex cdev_all_request_map_mutex_;
141     // Set of all request for a cooling device from each sensor
142     std::unordered_map<std::string, std::multiset<int, std::greater<int>>> cdev_all_request_map_;
143 };
144 
145 }  // namespace implementation
146 }  // namespace thermal
147 }  // namespace hardware
148 }  // namespace android
149 }  // namespace aidl
150