1 /*
2 * Copyright (C) 2019 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 #define LOG_TAG "libpixelpowerstats"
17
18 #include "IaxxxStateResidencyDataProvider.h"
19
20 #include <android-base/logging.h>
21 #include <android-base/unique_fd.h>
22 #include <fcntl.h>
23 #include <sys/ioctl.h>
24
25 #include <utility>
26
27 #include <linux/mfd/adnc/iaxxx-module.h>
28
29 namespace android {
30 namespace hardware {
31 namespace google {
32 namespace pixel {
33 namespace powerstats {
34
IaxxxStateResidencyDataProvider(uint32_t id)35 IaxxxStateResidencyDataProvider::IaxxxStateResidencyDataProvider(uint32_t id)
36 : mPath("/dev/iaxxx-module-celldrv"), mPowerEntityId(id) {}
37
getResults(std::unordered_map<uint32_t,PowerEntityStateResidencyResult> & results)38 bool IaxxxStateResidencyDataProvider::getResults(
39 std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
40 android::base::unique_fd devNode(open(mPath.c_str(), O_RDWR));
41 if (devNode.get() < 0) {
42 PLOG(ERROR) << __func__ << ":Failed to open file " << mPath;
43 return false;
44 }
45
46 struct iaxxx_pwr_stats pwrStatsCount;
47 int err = ioctl(devNode.get(), IAXXX_POWER_STATS_COUNT, &pwrStatsCount);
48 if (err != 0) {
49 PLOG(ERROR) << __func__ << "Failed to retrieve stats from " << mPath;
50 return false;
51 }
52
53 PowerEntityStateResidencyResult result = {.powerEntityId = mPowerEntityId};
54 hidl_vec<PowerEntityStateResidencyData> stateResidencyData;
55 stateResidencyData.resize(NUM_MPLL_CLK_FREQ + 1); // Each of the MPLL frequencies and sleep
56
57 // Populate stats for each MPLL frequency
58 for (uint32_t stateId = MPLL_CLK_3000; stateId != NUM_MPLL_CLK_FREQ; stateId++) {
59 stateResidencyData[stateId] = PowerEntityStateResidencyData{
60 .powerEntityStateId = stateId,
61 .totalTimeInStateMs = pwrStatsCount.mpllCumulativeDur[stateId],
62 .totalStateEntryCount = pwrStatsCount.mpll_cumulative_cnts[stateId],
63 .lastEntryTimestampMs = pwrStatsCount.mpllTimeStamp[stateId]};
64 }
65
66 // Populate stats for Sleep mode
67 stateResidencyData[NUM_MPLL_CLK_FREQ] = PowerEntityStateResidencyData{
68 .powerEntityStateId = NUM_MPLL_CLK_FREQ,
69 .totalTimeInStateMs = pwrStatsCount.sleepModeCumulativeDur,
70 .totalStateEntryCount = 0, // Sleep entry count is not available
71 .lastEntryTimestampMs = pwrStatsCount.sleepModeTimeStamp};
72
73 result.stateResidencyData = stateResidencyData;
74 results.insert(std::make_pair(mPowerEntityId, result));
75 return true;
76 }
77
getStateSpaces()78 std::vector<PowerEntityStateSpace> IaxxxStateResidencyDataProvider::getStateSpaces() {
79 std::vector<PowerEntityStateSpace> stateSpace = {{.powerEntityId = mPowerEntityId}};
80 hidl_vec<PowerEntityStateInfo> states;
81 states.resize(NUM_MPLL_CLK_FREQ + 1); // Each of the MPLL frequencies and sleep
82 for (uint32_t stateId = MPLL_CLK_3000; stateId <= NUM_MPLL_CLK_FREQ; stateId++) {
83 states[stateId] = PowerEntityStateInfo{
84 .powerEntityStateId = stateId,
85 .powerEntityStateName = static_cast<std::string>(mStateNames[stateId])};
86 }
87 stateSpace[0].states = states;
88
89 return stateSpace;
90 }
91
92 } // namespace powerstats
93 } // namespace pixel
94 } // namespace google
95 } // namespace hardware
96 } // namespace android
97