1 /*
2 * Copyright (C) 2020 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 #include <PowerStatsAidl.h>
18 #include <ZumaProCommonDataProviders.h>
19 #include <AocStateResidencyDataProvider.h>
20 #include <CpupmStateResidencyDataProvider.h>
21 #include <DevfreqStateResidencyDataProvider.h>
22 #include <DisplayMrrStateResidencyDataProvider.h>
23 #include <AdaptiveDvfsStateResidencyDataProvider.h>
24 #include <TpuDvfsStateResidencyDataProvider.h>
25 #include <UfsStateResidencyDataProvider.h>
26 #include <dataproviders/GenericStateResidencyDataProvider.h>
27 #include <dataproviders/IioEnergyMeterDataProvider.h>
28 #include <dataproviders/PowerStatsEnergyConsumer.h>
29 #include <dataproviders/PowerStatsEnergyAttribution.h>
30 #include <dataproviders/PixelStateResidencyDataProvider.h>
31
32 #include <android-base/logging.h>
33 #include <android-base/properties.h>
34 #include <android/binder_manager.h>
35 #include <android/binder_process.h>
36 #include <log/log.h>
37 #include <sys/stat.h>
38
39 using aidl::android::hardware::power::stats::AdaptiveDvfsStateResidencyDataProvider;
40 using aidl::android::hardware::power::stats::AocStateResidencyDataProvider;
41 using aidl::android::hardware::power::stats::CpupmStateResidencyDataProvider;
42 using aidl::android::hardware::power::stats::DevfreqStateResidencyDataProvider;
43 using aidl::android::hardware::power::stats::DisplayMrrStateResidencyDataProvider;
44 using aidl::android::hardware::power::stats::DvfsStateResidencyDataProvider;
45 using aidl::android::hardware::power::stats::UfsStateResidencyDataProvider;
46 using aidl::android::hardware::power::stats::EnergyConsumerType;
47 using aidl::android::hardware::power::stats::GenericStateResidencyDataProvider;
48 using aidl::android::hardware::power::stats::IioEnergyMeterDataProvider;
49 using aidl::android::hardware::power::stats::PixelStateResidencyDataProvider;
50 using aidl::android::hardware::power::stats::PowerStatsEnergyConsumer;
51 using aidl::android::hardware::power::stats::TpuDvfsStateResidencyDataProvider;
52
53 // TODO (b/181070764) (b/182941084):
54 // Remove this when Wifi/BT energy consumption models are available or revert before ship
55 using aidl::android::hardware::power::stats::EnergyConsumerResult;
56 using aidl::android::hardware::power::stats::Channel;
57 using aidl::android::hardware::power::stats::EnergyMeasurement;
58 class PlaceholderEnergyConsumer : public PowerStats::IEnergyConsumer {
59 public:
PlaceholderEnergyConsumer(std::shared_ptr<PowerStats> p,EnergyConsumerType type,std::string name)60 PlaceholderEnergyConsumer(std::shared_ptr<PowerStats> p, EnergyConsumerType type,
61 std::string name) : kType(type), kName(name), mPowerStats(p), mChannelId(-1) {
62 std::vector<Channel> channels;
63 mPowerStats->getEnergyMeterInfo(&channels);
64
65 for (const auto &c : channels) {
66 if (c.name == "VSYS_PWR_WLAN_BT") {
67 mChannelId = c.id;
68 break;
69 }
70 }
71 }
getInfo()72 std::pair<EnergyConsumerType, std::string> getInfo() override { return {kType, kName}; }
73
getEnergyConsumed()74 std::optional<EnergyConsumerResult> getEnergyConsumed() override {
75 int64_t totalEnergyUWs = 0;
76 int64_t timestampMs = 0;
77 if (mChannelId != -1) {
78 std::vector<EnergyMeasurement> measurements;
79 if (mPowerStats->readEnergyMeter({mChannelId}, &measurements).isOk()) {
80 for (const auto &m : measurements) {
81 totalEnergyUWs += m.energyUWs;
82 timestampMs = m.timestampMs;
83 }
84 } else {
85 LOG(ERROR) << "Failed to read energy meter";
86 return {};
87 }
88 }
89
90 return EnergyConsumerResult{.timestampMs = timestampMs,
91 .energyUWs = totalEnergyUWs>>1};
92 }
93
getConsumerName()94 std::string getConsumerName() override {
95 return kName;
96 };
97
98 private:
99 const EnergyConsumerType kType;
100 const std::string kName;
101 std::shared_ptr<PowerStats> mPowerStats;
102 int32_t mChannelId;
103 };
104
addPlaceholderEnergyConsumers(std::shared_ptr<PowerStats> p)105 void addPlaceholderEnergyConsumers(std::shared_ptr<PowerStats> p) {
106 p->addEnergyConsumer(
107 std::make_unique<PlaceholderEnergyConsumer>(p, EnergyConsumerType::WIFI, "Wifi"));
108 p->addEnergyConsumer(
109 std::make_unique<PlaceholderEnergyConsumer>(p, EnergyConsumerType::BLUETOOTH, "BT"));
110 }
111
addAoC(std::shared_ptr<PowerStats> p)112 void addAoC(std::shared_ptr<PowerStats> p) {
113 // AoC clock is synced from "libaoc.c"
114 static const uint64_t AOC_CLOCK = 24576;
115 std::string base = "/sys/devices/platform/17000000.aoc/";
116 std::string prefix = base + "control/";
117
118 // Add AoC cores (a32, ff1, hf0, and hf1)
119 std::vector<std::pair<std::string, std::string>> coreIds = {
120 {"AoC-A32", prefix + "a32_"},
121 {"AoC-FF1", prefix + "ff1_"},
122 {"AoC-HF1", prefix + "hf1_"},
123 {"AoC-HF0", prefix + "hf0_"},
124 };
125 std::vector<std::pair<std::string, std::string>> coreStates = {
126 {"DWN", "off"}, {"RET", "retention"}, {"WFI", "wfi"}};
127 p->addStateResidencyDataProvider(std::make_unique<AocStateResidencyDataProvider>(coreIds,
128 coreStates, AOC_CLOCK));
129
130 // Add AoC voltage stats
131 std::vector<std::pair<std::string, std::string>> voltageIds = {
132 {"AoC-Voltage", prefix + "voltage_"},
133 };
134 std::vector<std::pair<std::string, std::string>> voltageStates = {{"NOM", "nominal"},
135 {"SUD", "super_underdrive"},
136 {"UUD", "ultra_underdrive"},
137 {"UD", "underdrive"}};
138 p->addStateResidencyDataProvider(
139 std::make_unique<AocStateResidencyDataProvider>(voltageIds, voltageStates, AOC_CLOCK));
140
141 // Add AoC monitor mode
142 std::vector<std::pair<std::string, std::string>> monitorIds = {
143 {"AoC", prefix + "monitor_"},
144 };
145 std::vector<std::pair<std::string, std::string>> monitorStates = {
146 {"MON", "mode"},
147 };
148 p->addStateResidencyDataProvider(
149 std::make_unique<AocStateResidencyDataProvider>(monitorIds, monitorStates, AOC_CLOCK));
150
151 // Add AoC restart count
152 const GenericStateResidencyDataProvider::StateResidencyConfig restartCountConfig = {
153 .entryCountSupported = true,
154 .entryCountPrefix = "",
155 .totalTimeSupported = false,
156 .lastEntrySupported = false,
157 };
158 const std::vector<std::pair<std::string, std::string>> restartCountHeaders = {
159 std::make_pair("RESTART", ""),
160 };
161 std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
162 cfgs.emplace_back(
163 generateGenericStateResidencyConfigs(restartCountConfig, restartCountHeaders),
164 "AoC-Count", "");
165 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
166 base + "restart_count", cfgs));
167 }
168
addDvfsStats(std::shared_ptr<PowerStats> p)169 void addDvfsStats(std::shared_ptr<PowerStats> p) {
170 // A constant to represent the number of nanoseconds in one millisecond
171 const int NS_TO_MS = 1000000;
172 std::string path = "/sys/devices/platform/acpm_stats/fvp_stats";
173
174 std::vector<std::pair<std::string, std::string>> adpCfgs = {
175 std::make_pair("CL0", "/sys/devices/system/cpu/cpufreq/policy0/stats"),
176 std::make_pair("CL1", "/sys/devices/system/cpu/cpufreq/policy4/stats"),
177 std::make_pair("CL2", "/sys/devices/system/cpu/cpufreq/policy7/stats"),
178 std::make_pair("MIF",
179 "/sys/devices/platform/17000010.devfreq_mif/devfreq/17000010.devfreq_mif")};
180
181 p->addStateResidencyDataProvider(std::make_unique<AdaptiveDvfsStateResidencyDataProvider>(
182 path, NS_TO_MS, adpCfgs));
183
184 std::vector<DvfsStateResidencyDataProvider::Config> cfgs;
185 cfgs.push_back({"AUR", {
186 std::make_pair("1065MHz", "1065000"),
187 std::make_pair("861MHz", "861000"),
188 std::make_pair("713MHz", "713000"),
189 std::make_pair("525MHz", "525000"),
190 std::make_pair("355MHz", "355000"),
191 std::make_pair("256MHz", "256000"),
192 std::make_pair("178MHz", "178000"),
193 }});
194
195 p->addStateResidencyDataProvider(std::make_unique<DvfsStateResidencyDataProvider>(
196 path, NS_TO_MS, cfgs));
197
198 // TPU DVFS
199 const int TICK_TO_MS = 100;
200 std::vector<std::string> freqs = {
201 "1119000",
202 "1066000",
203 "845000",
204 "712000",
205 "627000",
206 "455000",
207 "226000"
208 };
209 p->addStateResidencyDataProvider(std::make_unique<TpuDvfsStateResidencyDataProvider>(
210 "/sys/class/edgetpu/edgetpu-soc/device/tpu_usage", freqs, TICK_TO_MS));
211 }
212
addSoC(std::shared_ptr<PowerStats> p)213 void addSoC(std::shared_ptr<PowerStats> p) {
214 // A constant to represent the number of nanoseconds in one millisecond.
215 const int NS_TO_MS = 1000000;
216
217 // ACPM stats are reported in nanoseconds. The transform function
218 // converts nanoseconds to milliseconds.
219 std::function<uint64_t(uint64_t)> acpmNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
220 const GenericStateResidencyDataProvider::StateResidencyConfig lpmStateConfig = {
221 .entryCountSupported = true,
222 .entryCountPrefix = "success_count:",
223 .totalTimeSupported = true,
224 .totalTimePrefix = "total_time_ns:",
225 .totalTimeTransform = acpmNsToMs,
226 .lastEntrySupported = true,
227 .lastEntryPrefix = "last_entry_time_ns:",
228 .lastEntryTransform = acpmNsToMs,
229 };
230 const GenericStateResidencyDataProvider::StateResidencyConfig downStateConfig = {
231 .entryCountSupported = true,
232 .entryCountPrefix = "down_count:",
233 .totalTimeSupported = true,
234 .totalTimePrefix = "total_down_time_ns:",
235 .totalTimeTransform = acpmNsToMs,
236 .lastEntrySupported = true,
237 .lastEntryPrefix = "last_down_time_ns:",
238 .lastEntryTransform = acpmNsToMs,
239 };
240 const GenericStateResidencyDataProvider::StateResidencyConfig reqStateConfig = {
241 .entryCountSupported = true,
242 .entryCountPrefix = "req_up_count:",
243 .totalTimeSupported = true,
244 .totalTimePrefix = "total_req_up_time_ns:",
245 .totalTimeTransform = acpmNsToMs,
246 .lastEntrySupported = true,
247 .lastEntryPrefix = "last_req_up_time_ns:",
248 .lastEntryTransform = acpmNsToMs,
249
250 };
251 const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
252 std::make_pair("SICD", "SICD"),
253 std::make_pair("SLEEP", "SLEEP"),
254 std::make_pair("SLEEP_SLCMON", "SLEEP_SLCMON"),
255 std::make_pair("SLEEP_HSI1ON", "SLEEP_HSI1ON"),
256 std::make_pair("STOP", "STOP"),
257 };
258 const std::vector<std::pair<std::string, std::string>> mifReqStateHeaders = {
259 std::make_pair("AOC", "AOC"),
260 std::make_pair("GSA", "GSA"),
261 std::make_pair("TPU", "TPU"),
262 std::make_pair("AUR", "AUR"),
263 };
264 const std::vector<std::pair<std::string, std::string>> slcReqStateHeaders = {
265 std::make_pair("AOC", "AOC"),
266 };
267
268 std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
269 cfgs.emplace_back(generateGenericStateResidencyConfigs(lpmStateConfig, powerStateHeaders),
270 "LPM", "LPM:");
271 cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
272 "MIF", "MIF:");
273 cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, mifReqStateHeaders),
274 "MIF-REQ", "MIF_REQ:");
275 cfgs.emplace_back(generateGenericStateResidencyConfigs(downStateConfig, powerStateHeaders),
276 "SLC", "SLC:");
277 cfgs.emplace_back(generateGenericStateResidencyConfigs(reqStateConfig, slcReqStateHeaders),
278 "SLC-REQ", "SLC_REQ:");
279
280 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
281 "/sys/devices/platform/acpm_stats/soc_stats", cfgs));
282 }
283
setEnergyMeter(std::shared_ptr<PowerStats> p)284 void setEnergyMeter(std::shared_ptr<PowerStats> p) {
285 std::vector<const std::string> deviceNames { "s2mpg14-odpm", "s2mpg15-odpm" };
286 p->setEnergyMeterDataProvider(std::make_unique<IioEnergyMeterDataProvider>(deviceNames, true));
287 }
288
addCPUclusters(std::shared_ptr<PowerStats> p)289 void addCPUclusters(std::shared_ptr<PowerStats> p) {
290 // A constant to represent the number of nanoseconds in one millisecond.
291 const int NS_TO_MS = 1000000;
292
293 std::function<uint64_t(uint64_t)> acpmNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
294 const GenericStateResidencyDataProvider::StateResidencyConfig cpuStateConfig = {
295 .entryCountSupported = true,
296 .entryCountPrefix = "down_count:",
297 .totalTimeSupported = true,
298 .totalTimePrefix = "total_down_time_ns:",
299 .totalTimeTransform = acpmNsToMs,
300 .lastEntrySupported = true,
301 .lastEntryPrefix = "last_down_time_ns:",
302 .lastEntryTransform = acpmNsToMs,
303 };
304
305 const std::vector<std::pair<std::string, std::string>> cpuStateHeaders = {
306 std::make_pair("DOWN", ""),
307 };
308
309 std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
310 for (std::string name : {
311 "CLUSTER0",
312 "CLUSTER1",
313 "CLUSTER2"}) {
314 cfgs.emplace_back(generateGenericStateResidencyConfigs(cpuStateConfig, cpuStateHeaders),
315 name, name);
316 }
317
318 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
319 "/sys/devices/platform/acpm_stats/core_stats", cfgs));
320
321 CpupmStateResidencyDataProvider::Config config = {
322 .entities = {
323 std::make_pair("CPU0", "cpu0"),
324 std::make_pair("CPU1", "cpu1"),
325 std::make_pair("CPU2", "cpu2"),
326 std::make_pair("CPU3", "cpu3"),
327 std::make_pair("CPU4", "cpu4"),
328 std::make_pair("CPU5", "cpu5"),
329 std::make_pair("CPU6", "cpu6"),
330 std::make_pair("CPU7", "cpu7")},
331 .states = {
332 std::make_pair("DOWN", "[state1]")}};
333
334 CpupmStateResidencyDataProvider::SleepConfig sleepConfig = {"LPM:", "SLEEP", "total_time_ns:"};
335
336 p->addStateResidencyDataProvider(std::make_unique<CpupmStateResidencyDataProvider>(
337 "/sys/devices/system/cpu/cpupm/cpupm/time_in_state", config,
338 "/sys/devices/platform/acpm_stats/soc_stats", sleepConfig));
339
340 p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
341 EnergyConsumerType::CPU_CLUSTER, "CPUCL0", {"S4M_VDD_CPUCL0"}));
342 p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
343 EnergyConsumerType::CPU_CLUSTER, "CPUCL1", {"S2M_VDD_CPUCL1"}));
344 p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
345 EnergyConsumerType::CPU_CLUSTER, "CPUCL2", {"S3M_VDD_CPUCL2"}));
346 }
347
addGPU(std::shared_ptr<PowerStats> p)348 void addGPU(std::shared_ptr<PowerStats> p) {
349 // Add gpu energy consumer
350 std::map<std::string, int32_t> stateCoeffs;
351 std::string path = "/sys/devices/platform/1f000000.mali";
352
353 stateCoeffs = {
354 {"150000", 637},
355 {"302000", 1308},
356 {"337000", 1461},
357 {"376000", 1650},
358 {"419000", 1861},
359 {"467000", 2086},
360 {"521000", 2334},
361 {"580000", 2558},
362 {"649000", 2886},
363 {"723000", 3244},
364 {"807000", 3762},
365 {"890000", 4333}};
366
367 p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterAndAttrConsumer(p,
368 EnergyConsumerType::OTHER, "GPU", {"S2S_VDD_G3D"},
369 {{UID_TIME_IN_STATE, path + "/uid_time_in_state"}},
370 stateCoeffs));
371
372 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>("GPU",
373 path));
374 }
375
addMobileRadio(std::shared_ptr<PowerStats> p)376 void addMobileRadio(std::shared_ptr<PowerStats> p)
377 {
378 // A constant to represent the number of microseconds in one millisecond.
379 const int US_TO_MS = 1000;
380
381 // modem power_stats are reported in microseconds. The transform function
382 // converts microseconds to milliseconds.
383 std::function<uint64_t(uint64_t)> modemUsToMs = [](uint64_t a) { return a / US_TO_MS; };
384 const GenericStateResidencyDataProvider::StateResidencyConfig powerStateConfig = {
385 .entryCountSupported = true,
386 .entryCountPrefix = "count:",
387 .totalTimeSupported = true,
388 .totalTimePrefix = "duration_usec:",
389 .totalTimeTransform = modemUsToMs,
390 .lastEntrySupported = true,
391 .lastEntryPrefix = "last_entry_timestamp_usec:",
392 .lastEntryTransform = modemUsToMs,
393 };
394 const std::vector<std::pair<std::string, std::string>> powerStateHeaders = {
395 std::make_pair("SLEEP", "SLEEP:"),
396 };
397
398 std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
399 cfgs.emplace_back(generateGenericStateResidencyConfigs(powerStateConfig, powerStateHeaders),
400 "MODEM", "");
401
402 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
403 "/sys/devices/platform/cpif/modem/power_stats", cfgs));
404
405 p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterConsumer(p,
406 EnergyConsumerType::MOBILE_RADIO, "MODEM",
407 {"VSYS_PWR_MODEM", "VSYS_PWR_RFFE", "VSYS_PWR_MMWAVE"}));
408 }
409
addGNSS(std::shared_ptr<PowerStats> p)410 void addGNSS(std::shared_ptr<PowerStats> p)
411 {
412 // A constant to represent the number of microseconds in one millisecond.
413 const int US_TO_MS = 1000;
414
415 // gnss power_stats are reported in microseconds. The transform function
416 // converts microseconds to milliseconds.
417 std::function<uint64_t(uint64_t)> gnssUsToMs = [](uint64_t a) { return a / US_TO_MS; };
418
419 const GenericStateResidencyDataProvider::StateResidencyConfig gnssStateConfig = {
420 .entryCountSupported = true,
421 .entryCountPrefix = "count:",
422 .totalTimeSupported = true,
423 .totalTimePrefix = "duration_usec:",
424 .totalTimeTransform = gnssUsToMs,
425 .lastEntrySupported = true,
426 .lastEntryPrefix = "last_entry_timestamp_usec:",
427 .lastEntryTransform = gnssUsToMs,
428 };
429
430 // External GNSS power stats are controlled by GPS chip side. The power stats
431 // would not update while GPS chip is down. This means that GPS OFF state
432 // residency won't reflect the elapsed off time. So only GPS ON state
433 // residency is present.
434 const std::vector<std::pair<std::string, std::string>> gnssStateHeaders = {
435 std::make_pair("ON", "GPS_ON:"),
436 };
437
438 std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
439 cfgs.emplace_back(generateGenericStateResidencyConfigs(gnssStateConfig, gnssStateHeaders),
440 "GPS", "");
441
442 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
443 "/data/vendor/gps/power_stats", cfgs));
444 }
445
addPCIe(std::shared_ptr<PowerStats> p)446 void addPCIe(std::shared_ptr<PowerStats> p) {
447 // Add PCIe power entities for Modem and WiFi
448 const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
449 .entryCountSupported = true,
450 .entryCountPrefix = "Cumulative count:",
451 .totalTimeSupported = true,
452 .totalTimePrefix = "Cumulative duration msec:",
453 .lastEntrySupported = true,
454 .lastEntryPrefix = "Last entry timestamp msec:",
455 };
456 const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
457 std::make_pair("UP", "Link up:"),
458 std::make_pair("DOWN", "Link down:"),
459 };
460
461 // Add PCIe - Modem
462 const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieModemCfgs = {
463 {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "PCIe-Modem",
464 "Version: 1"}
465 };
466
467 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
468 "/sys/devices/platform/12100000.pcie/power_stats", pcieModemCfgs));
469
470 // Add PCIe - WiFi
471 const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> pcieWifiCfgs = {
472 {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders),
473 "PCIe-WiFi", "Version: 1"}
474 };
475
476 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
477 "/sys/devices/platform/13120000.pcie/power_stats", pcieWifiCfgs));
478
479 // Add PCIe Modem GEN
480 const GenericStateResidencyDataProvider::StateResidencyConfig modemGenStateConfig = {
481 .entryCountSupported = true,
482 .entryCountPrefix = "count:",
483 .totalTimeSupported = true,
484 .totalTimePrefix = "duration msec:",
485 };
486 const std::vector<std::pair<std::string, std::string>> modemGenStateHeaders = {
487 std::make_pair("GEN1", "Gen1:"),
488 std::make_pair("GEN3", "Gen3:"),
489 };
490 const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> modemGenCfgs = {
491 {generateGenericStateResidencyConfigs(modemGenStateConfig, modemGenStateHeaders),
492 "PCIe-Modem-GEN", "link_speed:"}
493 };
494 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
495 "/sys/devices/platform/12100000.pcie/link_duration", modemGenCfgs));
496 }
497
addWifi(std::shared_ptr<PowerStats> p)498 void addWifi(std::shared_ptr<PowerStats> p) {
499 // The transform function converts microseconds to milliseconds.
500 std::function<uint64_t(uint64_t)> usecToMs = [](uint64_t a) { return a / 1000; };
501 const GenericStateResidencyDataProvider::StateResidencyConfig stateConfig = {
502 .entryCountSupported = true,
503 .entryCountPrefix = "count:",
504 .totalTimeSupported = true,
505 .totalTimePrefix = "duration_usec:",
506 .totalTimeTransform = usecToMs,
507 .lastEntrySupported = true,
508 .lastEntryPrefix = "last_entry_timestamp_usec:",
509 .lastEntryTransform = usecToMs,
510 };
511 const GenericStateResidencyDataProvider::StateResidencyConfig pcieStateConfig = {
512 .entryCountSupported = true,
513 .entryCountPrefix = "count:",
514 .totalTimeSupported = true,
515 .totalTimePrefix = "duration_usec:",
516 .totalTimeTransform = usecToMs,
517 .lastEntrySupported = false,
518 };
519
520 const std::vector<std::pair<std::string, std::string>> stateHeaders = {
521 std::make_pair("AWAKE", "AWAKE:"),
522 std::make_pair("ASLEEP", "ASLEEP:"),
523
524 };
525 const std::vector<std::pair<std::string, std::string>> pcieStateHeaders = {
526 std::make_pair("L0", "L0:"),
527 std::make_pair("L1", "L1:"),
528 std::make_pair("L1_1", "L1_1:"),
529 std::make_pair("L1_2", "L1_2:"),
530 std::make_pair("L2", "L2:"),
531 };
532
533 const std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs = {
534 {generateGenericStateResidencyConfigs(stateConfig, stateHeaders), "WIFI", "WIFI"},
535 {generateGenericStateResidencyConfigs(pcieStateConfig, pcieStateHeaders), "WIFI-PCIE",
536 "WIFI-PCIE"}
537 };
538
539 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
540 "/sys/wifi/power_stats", cfgs));
541 }
542
addUfs(std::shared_ptr<PowerStats> p)543 void addUfs(std::shared_ptr<PowerStats> p) {
544 p->addStateResidencyDataProvider(std::make_unique<UfsStateResidencyDataProvider>(
545 "/sys/bus/platform/devices/13200000.ufs/ufs_stats/"));
546 }
547
addPowerDomains(std::shared_ptr<PowerStats> p)548 void addPowerDomains(std::shared_ptr<PowerStats> p) {
549 // A constant to represent the number of nanoseconds in one millisecond.
550 const int NS_TO_MS = 1000000;
551
552 std::function<uint64_t(uint64_t)> acpmNsToMs = [](uint64_t a) { return a / NS_TO_MS; };
553 const GenericStateResidencyDataProvider::StateResidencyConfig cpuStateConfig = {
554 .entryCountSupported = true,
555 .entryCountPrefix = "on_count:",
556 .totalTimeSupported = true,
557 .totalTimePrefix = "total_on_time_ns:",
558 .totalTimeTransform = acpmNsToMs,
559 .lastEntrySupported = true,
560 .lastEntryPrefix = "last_on_time_ns:",
561 .lastEntryTransform = acpmNsToMs,
562 };
563
564 const std::vector<std::pair<std::string, std::string>> cpuStateHeaders = {
565 std::make_pair("ON", ""),
566 };
567
568 std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
569 for (std::string name : {
570 "pd-hsi0",
571 "pd-tpu",
572 "pd-ispfe",
573 "pd-eh",
574 "pd-bw",
575 "pd-aur",
576 "pd-yuvp",
577 "pd-tnr",
578 "pd-rgbp",
579 "pd-mfc",
580 "pd-mcsc",
581 "pd-gse",
582 "pd-gdc",
583 "pd-g2d",
584 "pd-dpuf1",
585 "pd-dpuf0",
586 "pd-dpub",
587 "pd-embedded_g3d",
588 "pd-g3d"}) {
589 cfgs.emplace_back(generateGenericStateResidencyConfigs(cpuStateConfig, cpuStateHeaders),
590 name, name + ":");
591 }
592
593 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
594 "/sys/devices/platform/acpm_stats/pd_stats", cfgs));
595 }
596
addDevfreq(std::shared_ptr<PowerStats> p)597 void addDevfreq(std::shared_ptr<PowerStats> p) {
598 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
599 "INT",
600 "/sys/devices/platform/17000020.devfreq_int/devfreq/17000020.devfreq_int"));
601
602 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
603 "INTCAM",
604 "/sys/devices/platform/17000030.devfreq_intcam/devfreq/17000030.devfreq_intcam"));
605
606 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
607 "DISP",
608 "/sys/devices/platform/17000040.devfreq_disp/devfreq/17000040.devfreq_disp"));
609
610 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
611 "CAM",
612 "/sys/devices/platform/17000050.devfreq_cam/devfreq/17000050.devfreq_cam"));
613
614 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
615 "TNR",
616 "/sys/devices/platform/17000060.devfreq_tnr/devfreq/17000060.devfreq_tnr"));
617
618 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
619 "MFC",
620 "/sys/devices/platform/17000070.devfreq_mfc/devfreq/17000070.devfreq_mfc"));
621
622 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
623 "BW",
624 "/sys/devices/platform/17000080.devfreq_bw/devfreq/17000080.devfreq_bw"));
625
626 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
627 "DSU",
628 "/sys/devices/platform/17000090.devfreq_dsu/devfreq/17000090.devfreq_dsu"));
629
630 p->addStateResidencyDataProvider(std::make_unique<DevfreqStateResidencyDataProvider>(
631 "BCI",
632 "/sys/devices/platform/170000a0.devfreq_bci/devfreq/170000a0.devfreq_bci"));
633 }
634
addTPU(std::shared_ptr<PowerStats> p)635 void addTPU(std::shared_ptr<PowerStats> p) {
636 std::map<std::string, int32_t> stateCoeffs;
637
638 stateCoeffs = {
639 // TODO (b/197721618): Measuring the TPU power numbers
640 {"226000", 10},
641 {"455000", 20},
642 {"627000", 30},
643 {"712000", 40},
644 {"845000", 50},
645 {"967000", 60}, // Do not change to 1066000
646 {"1119000", 70}};
647
648 p->addEnergyConsumer(PowerStatsEnergyConsumer::createMeterAndAttrConsumer(p,
649 EnergyConsumerType::OTHER, "TPU", {"S7M_VDD_TPU"},
650 {{UID_TIME_IN_STATE, "/sys/class/edgetpu/edgetpu-soc/device/tpu_usage"}},
651 stateCoeffs));
652 }
653
654 /**
655 * Unlike other data providers, which source power entity state residency data from the kernel,
656 * this data provider acts as a general-purpose channel for state residency data providers
657 * that live in user space. Entities are defined here and user space clients of this provider's
658 * vendor service register callbacks to provide state residency data for their given pwoer entity.
659 */
addPixelStateResidencyDataProvider(std::shared_ptr<PowerStats> p,std::string displayName)660 void addPixelStateResidencyDataProvider(std::shared_ptr<PowerStats> p, std::string displayName) {
661
662 auto pixelSdp = std::make_unique<PixelStateResidencyDataProvider>();
663
664 // Bluetooth power stats are provided by BT HAL callback
665 pixelSdp->addEntity("Bluetooth", {{0, "Idle"}, {1, "Active"}, {2, "Tx"}, {3, "Rx"}});
666
667 // Display VRR power stats are provided by HWC callback. If display entity
668 // name is empty, the device doesn't support VRR power stats.
669 if (!displayName.empty()) {
670 pixelSdp->addEntity(displayName, {});
671 }
672
673 pixelSdp->start();
674
675 p->addStateResidencyDataProvider(std::move(pixelSdp));
676 }
677
addDisplayMrrByEntity(std::shared_ptr<PowerStats> p,std::string name,std::string path)678 void addDisplayMrrByEntity(std::shared_ptr<PowerStats> p, std::string name, std::string path) {
679 p->addStateResidencyDataProvider(std::make_unique<DisplayMrrStateResidencyDataProvider>(
680 name, path));
681 }
682
addDisplayMrr(std::shared_ptr<PowerStats> p)683 void addDisplayMrr(std::shared_ptr<PowerStats> p) {
684 addDisplayMrrByEntity(p, "Display", "/sys/class/drm/card0/device/primary-panel/");
685 }
686
addZumaProCommonDataProviders(std::shared_ptr<PowerStats> p)687 void addZumaProCommonDataProviders(std::shared_ptr<PowerStats> p) {
688 setEnergyMeter(p);
689
690 addAoC(p);
691 addCPUclusters(p);
692 addSoC(p);
693 addGNSS(p);
694 addMobileRadio(p);
695 addNFC(p);
696 addPCIe(p);
697 addWifi(p);
698 addTPU(p);
699 addUfs(p);
700 addPowerDomains(p);
701 addDvfsStats(p);
702 addDevfreq(p);
703 addGPU(p);
704 }
705
addNFC(std::shared_ptr<PowerStats> p)706 void addNFC(std::shared_ptr<PowerStats> p) {
707 const int I2C_COUNT = 10;
708 const GenericStateResidencyDataProvider::StateResidencyConfig nfcStateConfig = {
709 .entryCountSupported = true,
710 .entryCountPrefix = "Cumulative count:",
711 .totalTimeSupported = true,
712 .totalTimePrefix = "Cumulative duration msec:",
713 .lastEntrySupported = true,
714 .lastEntryPrefix = "Last entry timestamp msec:",
715 };
716 const std::vector<std::pair<std::string, std::string>> nfcStateHeaders = {
717 std::make_pair("IDLE", "Idle mode:"),
718 std::make_pair("ACTIVE", "Active mode:"),
719 std::make_pair("ACTIVE-RW", "Active Reader/Writer mode:"),
720 };
721
722 std::vector<GenericStateResidencyDataProvider::PowerEntityConfig> cfgs;
723 cfgs.emplace_back(generateGenericStateResidencyConfigs(nfcStateConfig, nfcStateHeaders),
724 "NFC", "NFC subsystem");
725
726 std::string path;
727 struct stat buffer;
728 for (int i = 0; i < I2C_COUNT; i++) {
729 std::string idx = std::to_string(i);
730 path = "/sys/devices/platform/10c90000.hsi2c/i2c-" + idx + "/" + idx + "-0008/power_stats";
731 if (!stat(path.c_str(), &buffer))
732 break;
733 }
734 p->addStateResidencyDataProvider(std::make_unique<GenericStateResidencyDataProvider>(
735 path, cfgs));
736 }
737