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 "GpuStateResidencyDataProvider.h"
19 
20 #include <android-base/logging.h>
21 
22 #include <fstream>
23 #include <sstream>
24 
25 namespace android {
26 namespace hardware {
27 namespace google {
28 namespace pixel {
29 namespace powerstats {
30 
GpuStateResidencyDataProvider(uint32_t id)31 GpuStateResidencyDataProvider::GpuStateResidencyDataProvider(uint32_t id)
32     : mPowerEntityId(id), mActiveId(0) /* (TODO (b/117228832): enable this) , mSuspendId(1) */ {}
33 
getTotalTime(const std::string & path,uint64_t & totalTimeMs)34 bool GpuStateResidencyDataProvider::getTotalTime(const std::string &path, uint64_t &totalTimeMs) {
35     std::ifstream inFile(path, std::ifstream::in);
36     if (!inFile.is_open()) {
37         PLOG(ERROR) << __func__ << ":Failed to open file " << path;
38         return false;
39     }
40 
41     std::string line;
42     std::getline(inFile, line);
43     std::istringstream lineStream(line, std::istringstream::in);
44 
45     totalTimeMs = 0;
46     uint64_t curTimeMs = 0;
47     while (lineStream >> curTimeMs) {
48         totalTimeMs += curTimeMs;
49     }
50     return true;
51 }
52 
getResults(std::unordered_map<uint32_t,PowerEntityStateResidencyResult> & results)53 bool GpuStateResidencyDataProvider::getResults(
54     std::unordered_map<uint32_t, PowerEntityStateResidencyResult> &results) {
55     uint64_t totalActiveTimeUs = 0;
56     if (!getTotalTime("/sys/class/kgsl/kgsl-3d0/gpu_clock_stats", totalActiveTimeUs)) {
57         LOG(ERROR) << __func__ << "Failed to get results for GPU:Active";
58         return false;
59     }
60 
61     /* (TODO (b/117228832): enable this)
62     uint64_t totalSuspendTimeMs = 0;
63     if (!getTotalTime("/sys/class/kgsl/kgsl-3d0/devfreq/suspend_time", totalSuspendTimeMs)) {
64         LOG(ERROR) << __func__ << "Failed to get results for GPU:Suspend";
65         return false;
66     }
67     */
68 
69     PowerEntityStateResidencyResult result = {
70         .powerEntityId = mPowerEntityId,
71         .stateResidencyData = {
72             {.powerEntityStateId = mActiveId, .totalTimeInStateMs = totalActiveTimeUs / 1000},
73             /* (TODO (b/117228832): enable this)
74             {.powerEntityStateId = mSuspendId, .totalTimeInStateMs = totalSuspendTimeMs},
75             */
76         }};
77 
78     results.emplace(std::make_pair(mPowerEntityId, result));
79     return true;
80 }
81 
getStateSpaces()82 std::vector<PowerEntityStateSpace> GpuStateResidencyDataProvider::getStateSpaces() {
83     return {{.powerEntityId = mPowerEntityId,
84              .states = {
85                  {.powerEntityStateId = mActiveId, .powerEntityStateName = "Active"},
86                  /* (TODO (b/117228832): enable this)
87                  {.powerEntityStateId = mSuspendId, .powerEntityStateName = "Suspend"}
88                  */
89              }}};
90 }
91 
92 }  // namespace powerstats
93 }  // namespace pixel
94 }  // namespace google
95 }  // namespace hardware
96 }  // namespace android