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