summaryrefslogtreecommitdiff
path: root/power
diff options
context:
space:
mode:
authorBadhri Jagan Sridharan <Badhri@google.com>2016-04-03 22:23:59 -0700
committerBadhri Jagan Sridharan <Badhri@google.com>2016-04-25 13:08:18 -0700
commit2d10ac091ce925ebfb159a5e1e6b66731afe9920 (patch)
tree9bb33fc0dd28304b3a3fb9f89a99e0780b49cd09 /power
parent7bc6376ec69c0bbc726304092168a0465f6b9d23 (diff)
downloadangler-2d10ac091ce925ebfb159a5e1e6b66731afe9920.tar.gz
power: Add Platform-level sleep state stats for angler
Change-Id: I12ff2260a28584d2db6289f062ce44d7d486b18c
Diffstat (limited to 'power')
-rw-r--r--power/power.c151
1 files changed, 150 insertions, 1 deletions
diff --git a/power/power.c b/power/power.c
index 92fefc6..cff60c9 100644
--- a/power/power.c
+++ b/power/power.c
@@ -30,6 +30,7 @@
#define LOG_NIDEBUG 0
#include <errno.h>
+#include <inttypes.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -56,6 +57,36 @@
#define CPU6_ONLINE_PATH "/sys/devices/system/cpu/cpu6/online"
#define CPU7_ONLINE_PATH "/sys/devices/system/cpu/cpu7/online"
+#define PLATFORM_SLEEP_MODES 2
+#define XO_VOTERS 3
+#define VMIN_VOTERS 0
+
+#define RPM_PARAMETERS 4
+#define NUM_PARAMETERS 10
+
+#ifndef RPM_STAT
+#define RPM_STAT "/d/rpm_stats"
+#endif
+
+#ifndef RPM_MASTER_STAT
+#define RPM_MASTER_STAT "/d/rpm_master_stats"
+#endif
+
+/* RPM runs at 19.2Mhz. Divide by 19200 for msec */
+#define RPM_CLK 19200
+
+const char *parameter_names[] = {
+ "vlow_count",
+ "accumulated_vlow_time",
+ "vmin_count",
+ "accumulated_vmin_time",
+ "xo_accumulated_duration",
+ "xo_count",
+ "xo_accumulated_duration",
+ "xo_count",
+ "xo_accumulated_duration",
+ "xo_count"};
+
static int saved_dcvs_cpu0_slack_max = -1;
static int saved_dcvs_cpu0_slack_min = -1;
static int saved_mpdecision_slack_max = -1;
@@ -597,10 +628,125 @@ void set_interactive(struct power_module *module, int on)
saved_interactive_mode = !!on;
}
+static ssize_t get_number_of_platform_modes(struct power_module *module) {
+ return PLATFORM_SLEEP_MODES;
+}
+
+static int get_voter_list(struct power_module *module, size_t *voter) {
+ voter[0] = XO_VOTERS;
+ voter[1] = VMIN_VOTERS;
+
+ return 0;
+}
+
+static int extract_stats(uint64_t *list, char *file,
+ unsigned int num_parameters, unsigned int index) {
+ FILE *fp;
+ ssize_t read;
+ size_t len;
+ char *line;
+ int ret;
+
+ fp = fopen(file, "r");
+ if (fp == NULL) {
+ ret = -errno;
+ ALOGE("%s: failed to open: %s", __func__, strerror(errno));
+ return ret;
+ }
+
+ for (line = NULL, len = 0;
+ ((read = getline(&line, &len, fp) != -1) && (index < num_parameters));
+ free(line), line = NULL, len = 0) {
+ uint64_t value;
+ char* offset;
+
+ size_t begin = strspn(line, " \t");
+ if (strncmp(line + begin, parameter_names[index], strlen(parameter_names[index]))) {
+ continue;
+ }
+
+ offset = memchr(line, ':', len);
+ if (!offset) {
+ continue;
+ }
+
+ if (!strcmp(file, RPM_MASTER_STAT)) {
+ /* RPM_MASTER_STAT is reported in hex */
+ sscanf(offset, ":%" SCNx64, &value);
+ /* Duration is reported in rpm SLEEP TICKS */
+ if (!strcmp(parameter_names[index], "xo_accumulated_duration")) {
+ value /= RPM_CLK;
+ }
+ } else {
+ /* RPM_STAT is reported in decimal */
+ sscanf(offset, ":%" SCNu64, &value);
+ }
+ list[index] = value;
+ index++;
+ }
+ free(line);
+
+ fclose(fp);
+ return 0;
+}
+
+static int get_platform_low_power_stats(struct power_module *module,
+ power_state_platform_sleep_state_t *list) {
+ uint64_t stats[sizeof(parameter_names)] = {0};
+ int ret;
+
+ if (!list) {
+ return -EINVAL;
+ }
+
+ ret = extract_stats(stats, RPM_STAT, RPM_PARAMETERS, 0);
+
+ if (ret) {
+ return ret;
+ }
+
+ ret = extract_stats(stats, RPM_MASTER_STAT, NUM_PARAMETERS, 4);
+
+ if (ret) {
+ return ret;
+ }
+
+ /* Update statistics for XO_shutdown */
+ strcpy(list[0].name, "XO_shutdown");
+ list[0].total_transitions = stats[0];
+ list[0].residency_in_msec_since_boot = stats[1];
+ list[0].supported_only_in_suspend = false;
+ list[0].number_of_voters = XO_VOTERS;
+
+ /* Update statistics for APSS voter */
+ strcpy(list[0].voters[0].name, "APSS");
+ list[0].voters[0].total_time_in_msec_voted_for_since_boot = stats[4];
+ list[0].voters[0].total_number_of_times_voted_since_boot = stats[5];
+
+ /* Update statistics for MPSS voter */
+ strcpy(list[0].voters[1].name, "MPSS");
+ list[0].voters[1].total_time_in_msec_voted_for_since_boot = stats[6];
+ list[0].voters[1].total_number_of_times_voted_since_boot = stats[7];
+
+ /* Update statistics for LPASS voter */
+ strcpy(list[0].voters[2].name, "LPASS");
+ list[0].voters[2].total_time_in_msec_voted_for_since_boot = stats[8];
+ list[0].voters[2].total_number_of_times_voted_since_boot = stats[9];
+
+ /* Update statistics for VMIN state */
+ strcpy(list[1].name, "VMIN");
+ list[1].total_transitions = stats[2];
+ list[1].residency_in_msec_since_boot = stats[3];
+ list[1].supported_only_in_suspend = false;
+ list[1].number_of_voters = VMIN_VOTERS;
+
+ return 0;
+}
+
struct power_module HAL_MODULE_INFO_SYM = {
.common = {
.tag = HARDWARE_MODULE_TAG,
- .module_api_version = POWER_MODULE_API_VERSION_0_2,
+ .module_api_version = POWER_MODULE_API_VERSION_0_5,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = POWER_HARDWARE_MODULE_ID,
.name = "QCOM Power HAL",
@@ -611,4 +757,7 @@ struct power_module HAL_MODULE_INFO_SYM = {
.init = power_init,
.powerHint = power_hint,
.setInteractive = set_interactive,
+ .get_number_of_platform_modes = get_number_of_platform_modes,
+ .get_platform_low_power_stats = get_platform_low_power_stats,
+ .get_voter_list = get_voter_list
};