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 namespace aidl { 31 namespace android { 32 namespace hardware { 33 namespace thermal { 34 namespace implementation { 35 36 constexpr size_t kThrottlingSeverityCount = 37 std::distance(::ndk::enum_range<ThrottlingSeverity>().begin(), 38 ::ndk::enum_range<ThrottlingSeverity>().end()); 39 using ThrottlingArray = std::array<float, static_cast<size_t>(kThrottlingSeverityCount)>; 40 using CdevArray = std::array<int, static_cast<size_t>(kThrottlingSeverityCount)>; 41 constexpr std::chrono::milliseconds kMinPollIntervalMs = std::chrono::milliseconds(2000); 42 constexpr std::chrono::milliseconds kUeventPollTimeoutMs = std::chrono::milliseconds(300000); 43 // TODO(b/292044404): Add debug config to make them easily configurable 44 constexpr std::chrono::milliseconds kPowerLogIntervalMs = std::chrono::milliseconds(60000); 45 constexpr int kMaxPowerLogPerLine = 6; 46 // Max number of time_in_state buckets is 20 in atoms 47 // VendorSensorCoolingDeviceStats, VendorTempResidencyStats 48 constexpr int kMaxStatsResidencyCount = 20; 49 constexpr int kMaxStatsThresholdCount = kMaxStatsResidencyCount - 1; 50 51 enum FormulaOption : uint32_t { 52 COUNT_THRESHOLD = 0, 53 WEIGHTED_AVG, 54 MAXIMUM, 55 MINIMUM, 56 }; 57 58 template <typename T> 59 struct ThresholdList { 60 std::optional<std::string> logging_name; 61 std::vector<T> thresholds; ThresholdListThresholdList62 explicit ThresholdList(std::optional<std::string> logging_name, std::vector<T> thresholds) 63 : logging_name(logging_name), thresholds(thresholds) {} 64 65 ThresholdList() = default; 66 ThresholdList(const ThresholdList &) = default; 67 ThresholdList &operator=(const ThresholdList &) = default; 68 ThresholdList(ThresholdList &&) = default; 69 ThresholdList &operator=(ThresholdList &&) = default; 70 ~ThresholdList() = default; 71 }; 72 73 template <typename T> 74 struct StatsInfo { 75 // if bool, record all or none depending on flag 76 // if set, check name present in set 77 std::variant<bool, std::unordered_set<std::string> > 78 record_by_default_threshold_all_or_name_set_; 79 // map name to list of thresholds 80 std::unordered_map<std::string, std::vector<ThresholdList<T> > > record_by_threshold; clearStatsInfo81 void clear() { 82 record_by_default_threshold_all_or_name_set_ = false; 83 record_by_threshold.clear(); 84 } 85 }; 86 87 struct StatsConfig { 88 StatsInfo<float> sensor_stats_info; 89 StatsInfo<int> cooling_device_request_info; clearStatsConfig90 void clear() { 91 sensor_stats_info.clear(); 92 cooling_device_request_info.clear(); 93 } 94 }; 95 96 enum SensorFusionType : uint32_t { 97 SENSOR = 0, 98 ODPM, 99 CONSTANT, 100 }; 101 102 struct VirtualSensorInfo { 103 std::vector<std::string> linked_sensors; 104 std::vector<SensorFusionType> linked_sensors_type; 105 std::vector<std::string> coefficients; 106 std::vector<SensorFusionType> coefficients_type; 107 108 float offset; 109 std::vector<std::string> trigger_sensors; 110 FormulaOption formula; 111 }; 112 113 struct VirtualPowerRailInfo { 114 std::vector<std::string> linked_power_rails; 115 std::vector<float> coefficients; 116 float offset; 117 FormulaOption formula; 118 }; 119 120 // The method when the ODPM power is lower than threshold 121 enum ReleaseLogic : uint32_t { 122 INCREASE = 0, // Increase throttling by step 123 DECREASE, // Decrease throttling by step 124 STEPWISE, // Support both increase and decrease logix 125 RELEASE_TO_FLOOR, // Release throttling to floor directly 126 NONE, 127 }; 128 129 struct BindedCdevInfo { 130 CdevArray limit_info; 131 ThrottlingArray power_thresholds; 132 ReleaseLogic release_logic; 133 ThrottlingArray cdev_weight_for_pid; 134 CdevArray cdev_ceiling; 135 int max_release_step; 136 int max_throttle_step; 137 CdevArray cdev_floor_with_power_link; 138 std::string power_rail; 139 // The flag for activate release logic when power is higher than power threshold 140 bool high_power_check; 141 // The flag for only triggering throttling until all power samples are collected 142 bool throttling_with_power_link; 143 bool enabled; 144 }; 145 146 // The map to store the CDEV throttling info for each profile 147 using ProfileMap = std::unordered_map<std::string, std::unordered_map<std::string, BindedCdevInfo>>; 148 149 struct ThrottlingInfo { 150 ThrottlingArray k_po; 151 ThrottlingArray k_pu; 152 ThrottlingArray k_i; 153 ThrottlingArray k_d; 154 ThrottlingArray i_max; 155 ThrottlingArray max_alloc_power; 156 ThrottlingArray min_alloc_power; 157 ThrottlingArray s_power; 158 ThrottlingArray i_cutoff; 159 float i_default; 160 int tran_cycle; 161 std::unordered_map<std::string, ThrottlingArray> excluded_power_info_map; 162 std::unordered_map<std::string, BindedCdevInfo> binded_cdev_info_map; 163 ProfileMap profile_map; 164 }; 165 166 struct SensorInfo { 167 TemperatureType type; 168 ThrottlingArray hot_thresholds; 169 ThrottlingArray cold_thresholds; 170 ThrottlingArray hot_hysteresis; 171 ThrottlingArray cold_hysteresis; 172 std::string temp_path; 173 float vr_threshold; 174 float multiplier; 175 std::chrono::milliseconds polling_delay; 176 std::chrono::milliseconds passive_delay; 177 std::chrono::milliseconds time_resolution; 178 // The StepRatio value which is used for smoothing transient w/ the equation: 179 // Temp = CurrentTemp * StepRatio + LastTemp * (1 - StepRatio) 180 float step_ratio; 181 bool send_cb; 182 bool send_powerhint; 183 bool is_watch; 184 bool is_hidden; 185 std::unique_ptr<VirtualSensorInfo> virtual_sensor_info; 186 std::shared_ptr<ThrottlingInfo> throttling_info; 187 }; 188 189 struct CdevInfo { 190 CoolingType type; 191 std::string read_path; 192 std::string write_path; 193 std::vector<float> state2power; 194 int max_state; 195 }; 196 197 struct PowerRailInfo { 198 std::string rail; 199 int power_sample_count; 200 std::chrono::milliseconds power_sample_delay; 201 std::unique_ptr<VirtualPowerRailInfo> virtual_power_rail_info; 202 }; 203 204 bool ParseThermalConfig(std::string_view config_path, Json::Value *config); 205 bool ParseSensorInfo(const Json::Value &config, 206 std::unordered_map<std::string, SensorInfo> *sensors_parsed); 207 bool ParseCoolingDevice(const Json::Value &config, 208 std::unordered_map<std::string, CdevInfo> *cooling_device_parsed); 209 bool ParsePowerRailInfo(const Json::Value &config, 210 std::unordered_map<std::string, PowerRailInfo> *power_rail_parsed); 211 bool ParseStatsConfig(const Json::Value &config, 212 const std::unordered_map<std::string, SensorInfo> &sensor_info_map_, 213 const std::unordered_map<std::string, CdevInfo> &cooling_device_info_map_, 214 StatsConfig *stats_config); 215 } // namespace implementation 216 } // namespace thermal 217 } // namespace hardware 218 } // namespace android 219 } // namespace aidl 220