From 2a186347827d2caaed84e8bac4d2f02c162696a9 Mon Sep 17 00:00:00 2001 From: Subhajeet Muhuri Date: Sat, 25 Jan 2020 18:21:14 +0530 Subject: [PATCH] sdm660-common: power-libperfmgr: Add back powerstats Change-Id: I4343db7974eee74b6987e86e101cdfe6daff21a7 --- power-libperfmgr/Android.bp | 6 +- power-libperfmgr/hidl/Power.cpp | 62 ++++++++++- power-libperfmgr/hidl/power-helper.c | 156 +++++++++++++++++++++++++++ power-libperfmgr/hidl/power-helper.h | 69 ++++++++++++ 4 files changed, 288 insertions(+), 5 deletions(-) create mode 100644 power-libperfmgr/hidl/power-helper.c create mode 100644 power-libperfmgr/hidl/power-helper.h diff --git a/power-libperfmgr/Android.bp b/power-libperfmgr/Android.bp index 005f1979..f6feda7d 100644 --- a/power-libperfmgr/Android.bp +++ b/power-libperfmgr/Android.bp @@ -39,7 +39,11 @@ cc_binary { relative_install_path: "hw", vintf_fragments: ["hidl/android.hardware.power@1.3-service.xiaomi_sdm660.xml"], init_rc: ["hidl/android.hardware.power@1.3-service.xiaomi_sdm660-libperfmgr.rc"], - srcs: ["hidl/service.cpp", "hidl/Power.cpp"], + srcs: [ + "hidl/service.cpp", + "hidl/Power.cpp", + "hidl/power-helper.c", + ], cflags: [ "-Wall", "-Werror", diff --git a/power-libperfmgr/hidl/Power.cpp b/power-libperfmgr/hidl/Power.cpp index 0942a33e..703c2248 100644 --- a/power-libperfmgr/hidl/Power.cpp +++ b/power-libperfmgr/hidl/Power.cpp @@ -28,10 +28,17 @@ #include #include +#include "power-helper.h" + +/* RPM runs at 19.2Mhz. Divide by 19200 for msec */ +#define RPM_CLK 19200 + #ifndef TAP_TO_WAKE_NODE #define TAP_TO_WAKE_NODE "/sys/touchpanel/double_tap" #endif +extern struct stat_pair rpm_stat_map[]; + namespace android { namespace hardware { namespace power { @@ -42,7 +49,10 @@ using ::android::hardware::hidl_vec; using ::android::hardware::Return; using ::android::hardware::Void; using ::android::hardware::power::V1_0::Feature; +using ::android::hardware::power::V1_0::PowerStatePlatformSleepState; using ::android::hardware::power::V1_0::Status; +using ::android::hardware::power::V1_1::PowerStateSubsystem; +using ::android::hardware::power::V1_1::PowerStateSubsystemSleepState; constexpr char kPowerHalStateProp[] = "vendor.powerhal.state"; constexpr char kPowerHalAudioProp[] = "vendor.powerhal.audio"; @@ -152,15 +162,59 @@ Return Power::setFeature(Feature feature, bool activate) { } Return Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) { - LOG(ERROR) << "getPlatformLowPowerStats not supported. Use IPowerStats HAL."; - _hidl_cb({}, Status::SUCCESS); + + hidl_vec states; + uint64_t stats[MAX_PLATFORM_STATS * MAX_RPM_PARAMS] = {0}; + uint64_t *values; + struct PowerStatePlatformSleepState *state; + int ret; + + states.resize(PLATFORM_SLEEP_MODES_COUNT); + + ret = extract_platform_stats(stats); + if (ret != 0) { + states.resize(0); + goto done; + } + + /* Update statistics for XO_shutdown */ + state = &states[RPM_MODE_XO]; + state->name = "XO_shutdown"; + values = stats + (RPM_MODE_XO * MAX_RPM_PARAMS); + + state->residencyInMsecSinceBoot = values[1]; + state->totalTransitions = values[0]; + state->supportedOnlyInSuspend = false; + state->voters.resize(XO_VOTERS); + for(size_t i = 0; i < XO_VOTERS; i++) { + int voter = static_cast(i + XO_VOTERS_START); + state->voters[i].name = rpm_stat_map[voter].label; + values = stats + (voter * MAX_RPM_PARAMS); + state->voters[i].totalTimeInMsecVotedForSinceBoot = values[0] / RPM_CLK; + state->voters[i].totalNumberOfTimesVotedSinceBoot = values[1]; + } + + /* Update statistics for VMIN state */ + state = &states[RPM_MODE_VMIN]; + state->name = "VMIN"; + values = stats + (RPM_MODE_VMIN * MAX_RPM_PARAMS); + + state->residencyInMsecSinceBoot = values[1]; + state->totalTransitions = values[0]; + state->supportedOnlyInSuspend = false; + state->voters.resize(VMIN_VOTERS); + //Note: No filling of state voters since VMIN_VOTERS = 0 + +done: + _hidl_cb(states, Status::SUCCESS); return Void(); } // Methods from ::android::hardware::power::V1_1::IPower follow. Return Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) { - LOG(ERROR) << "getSubsystemLowPowerStats not supported. Use IPowerStats HAL."; - _hidl_cb({}, Status::SUCCESS); + hidl_vec subsystems; + subsystems.resize(0); + _hidl_cb(subsystems, Status::SUCCESS); return Void(); } diff --git a/power-libperfmgr/hidl/power-helper.c b/power-libperfmgr/hidl/power-helper.c new file mode 100644 index 00000000..c39ca689 --- /dev/null +++ b/power-libperfmgr/hidl/power-helper.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LOG_NIDEBUG 0 +#define LOG_TAG "android.hardware.power@1.3-service.xiaomi_sdm660-libperfmgr" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "power-helper.h" + +#ifndef RPM_SYSTEM_STAT +#define RPM_SYSTEM_STAT "/d/system_stats" +#endif + +#define ARRAY_SIZE(x) (sizeof((x))/sizeof((x)[0])) +#define LINE_SIZE 128 + +const char *rpm_stat_params[MAX_RPM_PARAMS] = { + "count", + "actual last sleep(msec)", +}; + +const char *master_stat_params[MAX_RPM_PARAMS] = { + "Accumulated XO duration", + "XO Count", +}; + +struct stat_pair rpm_stat_map[] = { + { RPM_MODE_XO, "RPM Mode:vlow", rpm_stat_params, ARRAY_SIZE(rpm_stat_params) }, + { RPM_MODE_VMIN, "RPM Mode:vmin", rpm_stat_params, ARRAY_SIZE(rpm_stat_params) }, + { VOTER_APSS, "APSS", master_stat_params, ARRAY_SIZE(master_stat_params) }, + { VOTER_MPSS, "MPSS", master_stat_params, ARRAY_SIZE(master_stat_params) }, + { VOTER_ADSP, "ADSP", master_stat_params, ARRAY_SIZE(master_stat_params) }, + { VOTER_SLPI, "SLPI", master_stat_params, ARRAY_SIZE(master_stat_params) }, +}; + +static int parse_stats(const char **params, size_t params_size, + uint64_t *list, FILE *fp) { + ssize_t nread; + size_t len = LINE_SIZE; + char *line; + size_t params_read = 0; + size_t i; + + line = malloc(len); + if (!line) { + ALOGE("%s: no memory to hold line", __func__); + return -ENOMEM; + } + + while ((params_read < params_size) && + (nread = getline(&line, &len, fp) > 0)) { + char *key = line + strspn(line, " \t"); + char *value = strchr(key, ':'); + if (!value || (value > (line + len))) + continue; + *value++ = '\0'; + + for (i = 0; i < params_size; i++) { + if (!strcmp(key, params[i])) { + list[i] = strtoull(value, NULL, 0); + params_read++; + break; + } + } + } + free(line); + + return 0; +} + + +static int extract_stats(uint64_t *list, char *file, + struct stat_pair *map, size_t map_size) { + FILE *fp; + ssize_t read; + size_t len = LINE_SIZE; + char *line; + size_t i, stats_read = 0; + int ret = 0; + + fp = fopen(file, "re"); + if (fp == NULL) { + ALOGE("%s: failed to open: %s Error = %s", __func__, file, strerror(errno)); + return -errno; + } + + line = malloc(len); + if (!line) { + ALOGE("%s: no memory to hold line", __func__); + fclose(fp); + return -ENOMEM; + } + + while ((stats_read < map_size) && (read = getline(&line, &len, fp) != -1)) { + size_t begin = strspn(line, " \t"); + + for (i = 0; i < map_size; i++) { + if (!strncmp(line + begin, map[i].label, strlen(map[i].label))) { + stats_read++; + break; + } + } + + if (i == map_size) + continue; + + ret = parse_stats(map[i].parameters, map[i].num_parameters, + &list[map[i].stat * MAX_RPM_PARAMS], fp); + if (ret < 0) + break; + } + free(line); + fclose(fp); + + return ret; +} + +int extract_platform_stats(uint64_t *list) { + return extract_stats(list, RPM_SYSTEM_STAT, rpm_stat_map, ARRAY_SIZE(rpm_stat_map)); +} diff --git a/power-libperfmgr/hidl/power-helper.h b/power-libperfmgr/hidl/power-helper.h new file mode 100644 index 00000000..70621d93 --- /dev/null +++ b/power-libperfmgr/hidl/power-helper.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2018, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __POWER_HELPER_H__ +#define __POWER_HELPER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +enum stats_type { + //Platform Stats + RPM_MODE_XO = 0, + RPM_MODE_VMIN, + RPM_MODE_MAX, + XO_VOTERS_START = RPM_MODE_MAX, + VOTER_APSS = XO_VOTERS_START, + VOTER_MPSS, + VOTER_ADSP, + VOTER_SLPI, + MAX_PLATFORM_STATS, +}; + +#define PLATFORM_SLEEP_MODES_COUNT RPM_MODE_MAX + +#define MAX_RPM_PARAMS 2 +#define XO_VOTERS (MAX_PLATFORM_STATS - XO_VOTERS_START) +#define VMIN_VOTERS 0 + +struct stat_pair { + enum stats_type stat; + const char *label; + const char **parameters; + size_t num_parameters; +}; + +int extract_platform_stats(uint64_t *list); + +#ifdef __cplusplus +} +#endif + +#endif //__POWER_HELPER_H__