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/CoolingType.h> 20 #include <aidl/android/hardware/thermal/TemperatureType.h> 21 #include <aidl/android/hardware/thermal/ThrottlingSeverity.h> 22 #include <json/value.h> 23 24 #include <chrono> 25 #include <string> 26 #include <unordered_map> 27 #include <unordered_set> 28 #include <variant> 29 30 #include "virtualtemp_estimator/virtualtemp_estimator.h" 31 32 namespace aidl { 33 namespace android { 34 namespace hardware { 35 namespace thermal { 36 namespace implementation { 37 38 constexpr size_t kThrottlingSeverityCount = 39 std::distance(::ndk::enum_range<ThrottlingSeverity>().begin(), 40 ::ndk::enum_range<ThrottlingSeverity>().end()); 41 using ThrottlingArray = std::array<float, static_cast<size_t>(kThrottlingSeverityCount)>; 42 using CdevArray = std::array<int, static_cast<size_t>(kThrottlingSeverityCount)>; 43 constexpr std::chrono::milliseconds kMinPollIntervalMs = std::chrono::milliseconds(2000); 44 constexpr std::chrono::milliseconds kUeventPollTimeoutMs = std::chrono::milliseconds(300000); 45 // TODO(b/292044404): Add debug config to make them easily configurable 46 constexpr std::chrono::milliseconds kPowerLogIntervalMs = std::chrono::milliseconds(60000); 47 constexpr int kMaxPowerLogPerLine = 6; 48 // Max number of time_in_state buckets is 20 in atoms 49 // VendorSensorCoolingDeviceStats, VendorTempResidencyStats 50 constexpr int kMaxStatsResidencyCount = 20; 51 constexpr int kMaxStatsThresholdCount = kMaxStatsResidencyCount - 1; 52 53 enum class FormulaOption : uint32_t { 54 COUNT_THRESHOLD = 0, 55 WEIGHTED_AVG, 56 MAXIMUM, 57 MINIMUM, 58 USE_ML_MODEL, 59 USE_LINEAR_MODEL, 60 PREVIOUSLY_PREDICTED 61 }; 62 63 template <typename T> 64 struct ThresholdList { 65 std::optional<std::string> logging_name; 66 std::vector<T> thresholds; ThresholdListThresholdList67 explicit ThresholdList(std::optional<std::string> logging_name, std::vector<T> thresholds) 68 : logging_name(logging_name), thresholds(thresholds) {} 69 70 ThresholdList() = default; 71 ThresholdList(const ThresholdList &) = default; 72 ThresholdList &operator=(const ThresholdList &) = default; 73 ThresholdList(ThresholdList &&) = default; 74 ThresholdList &operator=(ThresholdList &&) = default; 75 ~ThresholdList() = default; 76 }; 77 78 template <typename T> 79 struct StatsInfo { 80 // if bool, record all or none depending on flag 81 // if set, check name present in set 82 std::variant<bool, std::unordered_set<std::string> > 83 record_by_default_threshold_all_or_name_set_; 84 // map name to list of thresholds 85 std::unordered_map<std::string, std::vector<ThresholdList<T> > > record_by_threshold; clearStatsInfo86 void clear() { 87 record_by_default_threshold_all_or_name_set_ = false; 88 record_by_threshold.clear(); 89 } 90 }; 91 92 struct StatsConfig { 93 StatsInfo<float> sensor_stats_info; 94 StatsInfo<int> cooling_device_request_info; clearStatsConfig95 void clear() { 96 sensor_stats_info.clear(); 97 cooling_device_request_info.clear(); 98 } 99 }; 100 101 struct TempRangeInfo { 102 int max_temp_threshold; 103 int min_temp_threshold; 104 }; 105 106 struct TempStuckInfo { 107 int min_polling_count; 108 std::chrono::milliseconds min_stuck_duration; 109 }; 110 111 struct AbnormalStatsInfo { 112 struct SensorsTempRangeInfo { 113 std::vector<std::string> sensors; 114 TempRangeInfo temp_range_info; 115 }; 116 struct SensorsTempStuckInfo { 117 std::vector<std::string> sensors; 118 TempStuckInfo temp_stuck_info; 119 }; 120 121 std::optional<TempRangeInfo> default_temp_range_info; 122 std::vector<SensorsTempRangeInfo> sensors_temp_range_infos; 123 std::optional<TempStuckInfo> default_temp_stuck_info; 124 std::vector<SensorsTempStuckInfo> sensors_temp_stuck_infos; 125 }; 126 127 enum class SensorFusionType : uint32_t { 128 SENSOR = 0, 129 ODPM, 130 CONSTANT, 131 CDEV, 132 }; 133 134 enum class SensorReadStatus : uint32_t { 135 OKAY = 0, 136 UNDER_COLLECTING, 137 ERROR, 138 }; 139 140 std::ostream &operator<<(std::ostream &os, const SensorFusionType &sensor_fusion_type); 141 142 struct VirtualSensorInfo { 143 std::vector<std::string> linked_sensors; 144 std::vector<SensorFusionType> linked_sensors_type; 145 std::vector<std::string> coefficients; 146 std::vector<SensorFusionType> coefficients_type; 147 148 float offset; 149 std::vector<std::string> trigger_sensors; 150 FormulaOption formula; 151 std::string vt_estimator_model_file; 152 std::unique_ptr<::thermal::vtestimator::VirtualTempEstimator> vt_estimator; 153 std::string backup_sensor; 154 }; 155 156 struct PredictorInfo { 157 std::string sensor; 158 bool support_pid_compensation; 159 std::vector<float> prediction_weights; 160 ThrottlingArray k_p_compensate; 161 162 bool supports_predictions; // Does this sensor support predictions 163 int prediction_sample_interval; // Interval between each predicted sample 164 int num_prediction_samples; // How many samples are predicted for each iteration 165 int prediction_duration; // Prediction duration for a PREDICTED sensor 166 }; 167 168 struct VirtualPowerRailInfo { 169 std::vector<std::string> linked_power_rails; 170 std::vector<float> coefficients; 171 float offset; 172 FormulaOption formula; 173 }; 174 175 // The method when the ODPM power is lower than threshold 176 enum class ReleaseLogic : uint32_t { 177 INCREASE = 0, // Increase throttling by step 178 DECREASE, // Decrease throttling by step 179 STEPWISE, // Support both increase and decrease logix 180 RELEASE_TO_FLOOR, // Release throttling to floor directly 181 NONE, 182 }; 183 184 struct BindedCdevInfo { 185 CdevArray limit_info; 186 ThrottlingArray power_thresholds; 187 ReleaseLogic release_logic; 188 ThrottlingArray cdev_weight_for_pid; 189 CdevArray cdev_ceiling; 190 int max_release_step; 191 int max_throttle_step; 192 CdevArray cdev_floor_with_power_link; 193 std::string power_rail; 194 // The flag for activate release logic when power is higher than power threshold 195 bool high_power_check; 196 // The flag for only triggering throttling until all power samples are collected 197 bool throttling_with_power_link; 198 bool enabled; 199 }; 200 201 // The map to store the CDEV throttling info for each profile 202 using ProfileMap = std::unordered_map<std::string, std::unordered_map<std::string, BindedCdevInfo>>; 203 204 struct ThrottlingInfo { 205 ThrottlingArray k_po; 206 ThrottlingArray k_pu; 207 ThrottlingArray k_io; 208 ThrottlingArray k_iu; 209 ThrottlingArray k_d; 210 ThrottlingArray i_max; 211 ThrottlingArray max_alloc_power; 212 ThrottlingArray min_alloc_power; 213 ThrottlingArray s_power; 214 ThrottlingArray i_cutoff; 215 float i_default; 216 float i_default_pct; 217 int tran_cycle; 218 std::unordered_map<std::string, ThrottlingArray> excluded_power_info_map; 219 std::unordered_map<std::string, BindedCdevInfo> binded_cdev_info_map; 220 ProfileMap profile_map; 221 }; 222 223 struct SensorInfo { 224 TemperatureType type; 225 ThrottlingArray hot_thresholds; 226 ThrottlingArray cold_thresholds; 227 ThrottlingArray hot_hysteresis; 228 ThrottlingArray cold_hysteresis; 229 std::string temp_path; 230 std::string severity_reference; 231 float vr_threshold; 232 float multiplier; 233 std::chrono::milliseconds polling_delay; 234 std::chrono::milliseconds passive_delay; 235 std::chrono::milliseconds time_resolution; 236 // The StepRatio value which is used for smoothing transient w/ the equation: 237 // Temp = CurrentTemp * StepRatio + LastTemp * (1 - StepRatio) 238 float step_ratio; 239 bool send_cb; 240 bool send_powerhint; 241 bool is_watch; 242 bool is_hidden; 243 ThrottlingSeverity log_level; 244 std::unique_ptr<VirtualSensorInfo> virtual_sensor_info; 245 std::shared_ptr<ThrottlingInfo> throttling_info; 246 std::unique_ptr<PredictorInfo> predictor_info; 247 }; 248 249 struct CdevInfo { 250 CoolingType type; 251 std::string read_path; 252 std::string write_path; 253 std::vector<float> state2power; 254 int max_state; 255 }; 256 257 struct PowerRailInfo { 258 int power_sample_count; 259 std::chrono::milliseconds power_sample_delay; 260 std::unique_ptr<VirtualPowerRailInfo> virtual_power_rail_info; 261 }; 262 263 bool LoadThermalConfig(std::string_view config_path, Json::Value *config); 264 bool ParseThermalConfig(std::string_view config_path, Json::Value *config, 265 std::unordered_set<std::string> *loaded_config_paths); 266 void MergeConfigEntries(Json::Value *config, Json::Value *sub_config, std::string_view member_name); 267 bool ParseSensorInfo(const Json::Value &config, 268 std::unordered_map<std::string, SensorInfo> *sensors_parsed); 269 bool ParseCoolingDevice(const Json::Value &config, 270 std::unordered_map<std::string, CdevInfo> *cooling_device_parsed); 271 bool ParsePowerRailInfo(const Json::Value &config, 272 std::unordered_map<std::string, PowerRailInfo> *power_rail_parsed); 273 bool ParseSensorStatsConfig(const Json::Value &config, 274 const std::unordered_map<std::string, SensorInfo> &sensor_info_map_, 275 StatsInfo<float> *sensor_stats_info_parsed, 276 AbnormalStatsInfo *abnormal_stats_info_parsed); 277 bool ParseCoolingDeviceStatsConfig( 278 const Json::Value &config, 279 const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map_, 280 StatsInfo<int> *cooling_device_request_info_parsed); 281 } // namespace implementation 282 } // namespace thermal 283 } // namespace hardware 284 } // namespace android 285 } // namespace aidl 286