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