blob: 15b07bfd4e5a325c9b21c14ec64aed9313f24856 [file] [log] [blame]
Anurag Singh9cec85b2012-09-04 21:46:24 -07001/*
Ananth Raghavan Subramaniane432dbf2017-03-24 16:30:12 -07002 * Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +02003 * Copyright (C) 2017 The Android Open Source Project
dianlujitao8df56d62018-01-18 21:24:30 +08004 * Copyright (C) 2017-2018 The LineageOS Project
Anurag Singh9cec85b2012-09-04 21:46:24 -07005 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are
8 * met:
9 * * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials provided
14 * with the distribution.
Duy Truong70222452013-02-10 06:35:11 -080015 * * Neither the name of The Linux Foundation nor the names of its
Anurag Singh9cec85b2012-09-04 21:46:24 -070016 * contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
20 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31
Anurag Singh6ec12062012-10-02 09:59:01 -070032#define LOG_NIDEBUG 0
33
Anurag Singh9cec85b2012-09-04 21:46:24 -070034#include <errno.h>
35#include <string.h>
36#include <sys/types.h>
37#include <sys/stat.h>
38#include <fcntl.h>
39#include <dlfcn.h>
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +020040#include <inttypes.h>
Anurag Singh9cec85b2012-09-04 21:46:24 -070041#include <stdlib.h>
Rashed Abdel-Tawab42eb1ee2017-12-26 23:11:03 +020042#include <unistd.h>
Anurag Singh9cec85b2012-09-04 21:46:24 -070043
44#define LOG_TAG "QCOM PowerHAL"
Rashed Abdel-Tawab42eb1ee2017-12-26 23:11:03 +020045#include <log/log.h>
Anurag Singh9cec85b2012-09-04 21:46:24 -070046#include <hardware/power.h>
47
Anurag Singh6ec12062012-10-02 09:59:01 -070048#include "utils.h"
Anurag Singh9cec85b2012-09-04 21:46:24 -070049#include "metadata-defs.h"
Anurag Singh6ec12062012-10-02 09:59:01 -070050#include "hint-data.h"
51#include "performance.h"
Anurag Singh057806b2013-04-16 16:53:45 -070052#include "power-common.h"
Keith Mok964d2552015-11-13 09:46:14 -080053#include "power-feature.h"
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -070054#include "power-helper.h"
55
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +020056#define USINSEC 1000000L
57#define NSINUS 1000L
58
59#ifndef RPM_STAT
60#define RPM_STAT "/d/rpm_stats"
61#endif
62
63#ifndef RPM_MASTER_STAT
64#define RPM_MASTER_STAT "/d/rpm_master_stats"
65#endif
66
67#ifndef RPM_SYSTEM_STAT
68#define RPM_SYSTEM_STAT "/d/system_stats"
69#endif
70
71/*
72 Set with TARGET_WLAN_POWER_STAT in BoardConfig.mk
73 Defaults to QCACLD3 path
74 Path for QCACLD3: /d/wlan0/power_stats
75 Path for QCACLD2 and Prima: /d/wlan_wcnss/power_stats
76 */
77
78#ifndef V1_0_HAL
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -070079#ifndef WLAN_POWER_STAT
80#define WLAN_POWER_STAT "/d/wlan0/power_stats"
81#endif
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +020082#endif
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -070083
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -070084#define LINE_SIZE 128
85
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +020086#ifdef LEGACY_STATS
87/* Use these stats on pre-nougat qualcomm kernels */
88static const char *rpm_param_names[] = {
89 "vlow_count",
90 "accumulated_vlow_time",
91 "vmin_count",
92 "accumulated_vmin_time"
93};
94
95static const char *rpm_master_param_names[] = {
96 "xo_accumulated_duration",
97 "xo_count",
98 "xo_accumulated_duration",
99 "xo_count",
100 "xo_accumulated_duration",
101 "xo_count",
102 "xo_accumulated_duration",
103 "xo_count"
104};
Rashed Abdel-Tawab031a2bc2018-01-09 20:31:32 -0500105
106static const char *wlan_param_names[] = {
107 "cumulative_sleep_time_ms",
108 "cumulative_total_on_time_ms",
109 "deep_sleep_enter_counter",
110 "last_deep_sleep_enter_tstamp_ms"
111};
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200112#else
Rashed Abdel-Tawab031a2bc2018-01-09 20:31:32 -0500113/* Use these stats on nougat kernels and forward */
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200114const char *rpm_stat_params[MAX_RPM_PARAMS] = {
115 "count",
116 "actual last sleep(msec)",
117};
118
119const char *master_stat_params[MAX_RPM_PARAMS] = {
120 "Accumulated XO duration",
121 "XO Count",
122};
123
124struct stat_pair rpm_stat_map[] = {
125 { RPM_MODE_XO, "RPM Mode:vlow", rpm_stat_params, ARRAY_SIZE(rpm_stat_params) },
126 { RPM_MODE_VMIN, "RPM Mode:vmin", rpm_stat_params, ARRAY_SIZE(rpm_stat_params) },
127 { VOTER_APSS, "APSS", master_stat_params, ARRAY_SIZE(master_stat_params) },
128 { VOTER_MPSS, "MPSS", master_stat_params, ARRAY_SIZE(master_stat_params) },
129 { VOTER_ADSP, "ADSP", master_stat_params, ARRAY_SIZE(master_stat_params) },
130 { VOTER_SLPI, "SLPI", master_stat_params, ARRAY_SIZE(master_stat_params) },
131};
132#endif
133
134#ifndef V1_0_HAL
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700135const char *wlan_power_stat_params[] = {
136 "cumulative_sleep_time_ms",
137 "cumulative_total_on_time_ms",
138 "deep_sleep_enter_counter",
139 "last_deep_sleep_enter_tstamp_ms"
140};
141
142struct stat_pair wlan_stat_map[] = {
143 { WLAN_POWER_DEBUG_STATS, "POWER DEBUG STATS", wlan_power_stat_params, ARRAY_SIZE(wlan_power_stat_params) },
144};
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200145#endif
Anurag Singh9cec85b2012-09-04 21:46:24 -0700146
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700147static int saved_dcvs_cpu0_slack_max = -1;
148static int saved_dcvs_cpu0_slack_min = -1;
149static int saved_mpdecision_slack_max = -1;
150static int saved_mpdecision_slack_min = -1;
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700151static int slack_node_rw_failed = 0;
Anurag Singhb15323a2013-06-08 16:55:44 -0700152static int display_hint_sent;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700153
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700154void power_init(void)
Anurag Singh9cec85b2012-09-04 21:46:24 -0700155{
156 ALOGI("QCOM power HAL initing.");
157}
158
Anurag Singh6ec12062012-10-02 09:59:01 -0700159static void process_video_decode_hint(void *metadata)
160{
161 char governor[80];
162 struct video_decode_metadata_t video_decode_metadata;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700163
Anurag Singh6ec12062012-10-02 09:59:01 -0700164 if (get_scaling_governor(governor, sizeof(governor)) == -1) {
165 ALOGE("Can't obtain scaling governor.");
Anurag Singh9cec85b2012-09-04 21:46:24 -0700166
Anurag Singh6ec12062012-10-02 09:59:01 -0700167 return;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700168 }
169
Anurag Singh6ec12062012-10-02 09:59:01 -0700170 if (metadata) {
171 ALOGI("Processing video decode hint. Metadata: %s", (char *)metadata);
172 }
173
174 /* Initialize encode metadata struct fields. */
175 memset(&video_decode_metadata, 0, sizeof(struct video_decode_metadata_t));
176 video_decode_metadata.state = -1;
177 video_decode_metadata.hint_id = DEFAULT_VIDEO_DECODE_HINT_ID;
178
179 if (metadata) {
180 if (parse_video_decode_metadata((char *)metadata, &video_decode_metadata) ==
181 -1) {
182 ALOGE("Error occurred while parsing metadata.");
183 return;
184 }
185 } else {
186 return;
187 }
188
189 if (video_decode_metadata.state == 1) {
Michael Bestase701b2d2018-03-25 23:14:21 +0300190 if (is_ondemand_governor(governor)) {
Vince Leungf72adfb2013-05-03 15:13:29 -0700191 int resource_values[] = {THREAD_MIGRATION_SYNC_OFF};
192
193 perform_hint_action(video_decode_metadata.hint_id,
Zhao Wei Liewa72f7772016-06-26 11:37:59 +0800194 resource_values, ARRAY_SIZE(resource_values));
Ethan Chened4628c2018-03-01 21:41:04 -0800195 } else if (is_interactive_governor(governor)) {
Vince Leungf72adfb2013-05-03 15:13:29 -0700196 int resource_values[] = {TR_MS_30, HISPEED_LOAD_90, HS_FREQ_1026, THREAD_MIGRATION_SYNC_OFF};
Anurag Singh6ec12062012-10-02 09:59:01 -0700197
198 perform_hint_action(video_decode_metadata.hint_id,
Zhao Wei Liewa72f7772016-06-26 11:37:59 +0800199 resource_values, ARRAY_SIZE(resource_values));
Anurag Singh6ec12062012-10-02 09:59:01 -0700200 }
201 } else if (video_decode_metadata.state == 0) {
Michael Bestase701b2d2018-03-25 23:14:21 +0300202 if (is_ondemand_governor(governor)) {
Paul Keith2d3df8b2016-07-31 19:22:50 -0700203 undo_hint_action(video_decode_metadata.hint_id);
Ethan Chened4628c2018-03-01 21:41:04 -0800204 } else if (is_interactive_governor(governor)) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700205 undo_hint_action(video_decode_metadata.hint_id);
206 }
207 }
Anurag Singh9cec85b2012-09-04 21:46:24 -0700208}
209
210static void process_video_encode_hint(void *metadata)
211{
Anurag Singh9cec85b2012-09-04 21:46:24 -0700212 char governor[80];
213 struct video_encode_metadata_t video_encode_metadata;
214
215 if (get_scaling_governor(governor, sizeof(governor)) == -1) {
216 ALOGE("Can't obtain scaling governor.");
217
218 return;
219 }
220
221 /* Initialize encode metadata struct fields. */
Anurag Singh6ec12062012-10-02 09:59:01 -0700222 memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t));
Anurag Singh9cec85b2012-09-04 21:46:24 -0700223 video_encode_metadata.state = -1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700224 video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700225
226 if (metadata) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700227 if (parse_video_encode_metadata((char *)metadata, &video_encode_metadata) ==
Anurag Singh9cec85b2012-09-04 21:46:24 -0700228 -1) {
229 ALOGE("Error occurred while parsing metadata.");
230 return;
231 }
232 } else {
233 return;
234 }
235
Anurag Singh6ec12062012-10-02 09:59:01 -0700236 if (video_encode_metadata.state == 1) {
Michael Bestase701b2d2018-03-25 23:14:21 +0300237 if (is_ondemand_governor(governor)) {
Vince Leungf72adfb2013-05-03 15:13:29 -0700238 int resource_values[] = {IO_BUSY_OFF, SAMPLING_DOWN_FACTOR_1, THREAD_MIGRATION_SYNC_OFF};
Anurag Singh9cec85b2012-09-04 21:46:24 -0700239
Anurag Singh6ec12062012-10-02 09:59:01 -0700240 perform_hint_action(video_encode_metadata.hint_id,
Zhao Wei Liewa72f7772016-06-26 11:37:59 +0800241 resource_values, ARRAY_SIZE(resource_values));
Ethan Chened4628c2018-03-01 21:41:04 -0800242 } else if (is_interactive_governor(governor)) {
Anurag Singh6cda91c2013-12-18 18:24:14 -0800243 int resource_values[] = {TR_MS_30, HISPEED_LOAD_90, HS_FREQ_1026, THREAD_MIGRATION_SYNC_OFF,
244 INTERACTIVE_IO_BUSY_OFF};
Anurag Singh9cec85b2012-09-04 21:46:24 -0700245
Anurag Singh6ec12062012-10-02 09:59:01 -0700246 perform_hint_action(video_encode_metadata.hint_id,
Zhao Wei Liewa72f7772016-06-26 11:37:59 +0800247 resource_values, ARRAY_SIZE(resource_values));
Anurag Singh6ec12062012-10-02 09:59:01 -0700248 }
249 } else if (video_encode_metadata.state == 0) {
Michael Bestase701b2d2018-03-25 23:14:21 +0300250 if (is_ondemand_governor(governor)) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700251 undo_hint_action(video_encode_metadata.hint_id);
Ethan Chened4628c2018-03-01 21:41:04 -0800252 } else if (is_interactive_governor(governor)) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700253 undo_hint_action(video_encode_metadata.hint_id);
Anurag Singh9cec85b2012-09-04 21:46:24 -0700254 }
255 }
256}
257
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700258int __attribute__ ((weak)) power_hint_override(power_hint_t UNUSED(hint),
Adrian Salidoa60e94b2017-03-29 15:58:38 -0700259 void *UNUSED(data))
Anurag Singh9cec85b2012-09-04 21:46:24 -0700260{
Anurag Singh057806b2013-04-16 16:53:45 -0700261 return HINT_NONE;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700262}
263
Ajay Dudani5e676802015-04-07 23:56:52 -0700264/* Declare function before use */
265void interaction(int duration, int num_args, int opt_list[]);
266
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700267void power_hint(power_hint_t hint, void *data)
Anurag Singh9cec85b2012-09-04 21:46:24 -0700268{
269 /* Check if this hint has been overridden. */
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700270 if (power_hint_override(hint, data) == HINT_HANDLED) {
Anurag Singh9cec85b2012-09-04 21:46:24 -0700271 /* The power_hint has been handled. We can skip the rest. */
272 return;
273 }
274
275 switch(hint) {
Ananth Raghavan Subramaniane432dbf2017-03-24 16:30:12 -0700276 case POWER_HINT_SUSTAINED_PERFORMANCE:
277 ALOGI("Sustained perf power hint not handled in power_hint_override");
Paul Keith4f2dadb2017-12-31 02:17:32 +0100278 break;
Ananth Raghavan Subramaniane432dbf2017-03-24 16:30:12 -0700279 case POWER_HINT_VR_MODE:
280 ALOGI("VR mode power hint not handled in power_hint_override");
Paul Keith4f2dadb2017-12-31 02:17:32 +0100281 break;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700282 case POWER_HINT_INTERACTION:
Vince Leung699c1bc2013-08-14 17:40:36 -0700283 {
284 int resources[] = {0x702, 0x20F, 0x30F};
285 int duration = 3000;
286
287 interaction(duration, sizeof(resources)/sizeof(resources[0]), resources);
288 }
Anurag Singh9cec85b2012-09-04 21:46:24 -0700289 break;
290 case POWER_HINT_VIDEO_ENCODE:
291 process_video_encode_hint(data);
292 break;
Anurag Singh6ec12062012-10-02 09:59:01 -0700293 case POWER_HINT_VIDEO_DECODE:
294 process_video_decode_hint(data);
295 break;
dianlujitao8df56d62018-01-18 21:24:30 +0800296 case POWER_HINT_SET_PROFILE:
297 ALOGI("set profile power hint not handled in power_hint_override");
298 break;
Paul Keith4f2dadb2017-12-31 02:17:32 +0100299 default:
300 break;
Anurag Singh9cec85b2012-09-04 21:46:24 -0700301 }
302}
303
dianlujitao8df56d62018-01-18 21:24:30 +0800304int get_number_of_profiles()
305{
306 return 0;
307}
308
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700309int __attribute__ ((weak)) set_interactive_override(int UNUSED(on))
Anurag Singh6ec12062012-10-02 09:59:01 -0700310{
Anurag Singh057806b2013-04-16 16:53:45 -0700311 return HINT_NONE;
Anurag Singh6ec12062012-10-02 09:59:01 -0700312}
313
Steve Kondik11a84642014-03-27 22:00:00 -0700314#ifdef SET_INTERACTIVE_EXT
315extern void power_set_interactive_ext(int on);
316#endif
317
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700318void power_set_interactive(int on)
Anurag Singh9cec85b2012-09-04 21:46:24 -0700319{
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700320 char governor[80];
321 char tmp_str[NODE_MAX];
Anurag Singh6ec12062012-10-02 09:59:01 -0700322 struct video_encode_metadata_t video_encode_metadata;
Krishna Vanka42c06e12016-08-29 16:38:54 +0530323 int rc = 0;
Anurag Singh6ec12062012-10-02 09:59:01 -0700324
Balamurugan Thanikachalam930f9ae2017-07-11 14:42:21 +0530325 if (!on) {
326 /* Send Display OFF hint to perf HAL */
327 perf_hint_enable(VENDOR_HINT_DISPLAY_OFF, 0);
328 } else {
329 /* Send Display ON hint to perf HAL */
330 perf_hint_enable(VENDOR_HINT_DISPLAY_ON, 0);
331 }
332
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800333 /**
334 * Ignore consecutive display-off hints
335 * Consecutive display-on hints are already handled
336 */
337 if (display_hint_sent && !on)
338 return;
339
340 display_hint_sent = !on;
341
Steve Kondik11a84642014-03-27 22:00:00 -0700342#ifdef SET_INTERACTIVE_EXT
343 power_set_interactive_ext(on);
344#endif
345
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700346 if (set_interactive_override(on) == HINT_HANDLED) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700347 return;
348 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700349
Anurag Singhb15323a2013-06-08 16:55:44 -0700350 ALOGI("Got set_interactive hint");
Anurag Singhfe93c1d2012-11-21 15:15:56 -0800351
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700352 if (get_scaling_governor(governor, sizeof(governor)) == -1) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700353 ALOGE("Can't obtain scaling governor.");
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700354
355 return;
356 }
357
Anurag Singh6ec12062012-10-02 09:59:01 -0700358 if (!on) {
359 /* Display off. */
Michael Bestase701b2d2018-03-25 23:14:21 +0300360 if (is_ondemand_governor(governor)) {
Zhao Wei Liew40ec34d2016-06-26 11:45:11 +0800361 int resource_values[] = { MS_500, THREAD_MIGRATION_SYNC_OFF };
Anurag Singh10918c12012-11-09 17:35:20 -0800362
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800363 perform_hint_action(DISPLAY_STATE_HINT_ID,
364 resource_values, ARRAY_SIZE(resource_values));
Ethan Chened4628c2018-03-01 21:41:04 -0800365 } else if (is_interactive_governor(governor)) {
Dilip Gudlur2eae2662014-02-25 12:32:37 -0800366 int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF};
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700367
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800368 perform_hint_action(DISPLAY_STATE_HINT_ID,
369 resource_values, ARRAY_SIZE(resource_values));
Michael Bestase701b2d2018-03-25 23:14:21 +0300370 } else if (is_msmdcvs_governor(governor)) {
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800371 /* Display turned off. */
372 if (sysfs_read(DCVS_CPU0_SLACK_MAX_NODE, tmp_str, NODE_MAX - 1)) {
373 if (!slack_node_rw_failed) {
374 ALOGE("Failed to read from %s", DCVS_CPU0_SLACK_MAX_NODE);
375 }
376
377 rc = 1;
378 } else {
379 saved_dcvs_cpu0_slack_max = atoi(tmp_str);
380 }
381
382 if (sysfs_read(DCVS_CPU0_SLACK_MIN_NODE, tmp_str, NODE_MAX - 1)) {
383 if (!slack_node_rw_failed) {
384 ALOGE("Failed to read from %s", DCVS_CPU0_SLACK_MIN_NODE);
385 }
386
387 rc = 1;
388 } else {
389 saved_dcvs_cpu0_slack_min = atoi(tmp_str);
390 }
391
392 if (sysfs_read(MPDECISION_SLACK_MAX_NODE, tmp_str, NODE_MAX - 1)) {
393 if (!slack_node_rw_failed) {
394 ALOGE("Failed to read from %s", MPDECISION_SLACK_MAX_NODE);
395 }
396
397 rc = 1;
398 } else {
399 saved_mpdecision_slack_max = atoi(tmp_str);
400 }
401
402 if (sysfs_read(MPDECISION_SLACK_MIN_NODE, tmp_str, NODE_MAX - 1)) {
403 if(!slack_node_rw_failed) {
404 ALOGE("Failed to read from %s", MPDECISION_SLACK_MIN_NODE);
405 }
406
407 rc = 1;
408 } else {
409 saved_mpdecision_slack_min = atoi(tmp_str);
410 }
411
412 /* Write new values. */
413 if (saved_dcvs_cpu0_slack_max != -1) {
414 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_dcvs_cpu0_slack_max);
415
416 if (sysfs_write(DCVS_CPU0_SLACK_MAX_NODE, tmp_str) != 0) {
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700417 if (!slack_node_rw_failed) {
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800418 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MAX_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700419 }
420
421 rc = 1;
422 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800423 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700424
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800425 if (saved_dcvs_cpu0_slack_min != -1) {
426 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_dcvs_cpu0_slack_min);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700427
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800428 if (sysfs_write(DCVS_CPU0_SLACK_MIN_NODE, tmp_str) != 0) {
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700429 if(!slack_node_rw_failed) {
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800430 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MIN_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700431 }
432
433 rc = 1;
434 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800435 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700436
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800437 if (saved_mpdecision_slack_max != -1) {
438 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_mpdecision_slack_max);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700439
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800440 if (sysfs_write(MPDECISION_SLACK_MAX_NODE, tmp_str) != 0) {
441 if(!slack_node_rw_failed) {
442 ALOGE("Failed to write to %s", MPDECISION_SLACK_MAX_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700443 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800444
445 rc = 1;
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700446 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800447 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700448
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800449 if (saved_mpdecision_slack_min != -1) {
450 snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_mpdecision_slack_min);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700451
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800452 if (sysfs_write(MPDECISION_SLACK_MIN_NODE, tmp_str) != 0) {
453 if(!slack_node_rw_failed) {
454 ALOGE("Failed to write to %s", MPDECISION_SLACK_MIN_NODE);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700455 }
456
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800457 rc = 1;
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700458 }
459 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700460
461 slack_node_rw_failed = rc;
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700462 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700463 } else {
464 /* Display on. */
Michael Bestase701b2d2018-03-25 23:14:21 +0300465 if (is_ondemand_governor(governor)) {
Anurag Singh10918c12012-11-09 17:35:20 -0800466 undo_hint_action(DISPLAY_STATE_HINT_ID);
Ethan Chened4628c2018-03-01 21:41:04 -0800467 } else if (is_interactive_governor(governor)) {
Anurag Singh6ec12062012-10-02 09:59:01 -0700468 undo_hint_action(DISPLAY_STATE_HINT_ID);
Michael Bestase701b2d2018-03-25 23:14:21 +0300469 } else if (is_msmdcvs_governor(governor)) {
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800470 /* Display turned on. Restore if possible. */
471 if (saved_dcvs_cpu0_slack_max != -1) {
472 snprintf(tmp_str, NODE_MAX, "%d", saved_dcvs_cpu0_slack_max);
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700473
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800474 if (sysfs_write(DCVS_CPU0_SLACK_MAX_NODE, tmp_str) != 0) {
475 if (!slack_node_rw_failed) {
476 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MAX_NODE);
Anurag Singh6ec12062012-10-02 09:59:01 -0700477 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800478
479 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700480 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800481 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700482
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800483 if (saved_dcvs_cpu0_slack_min != -1) {
484 snprintf(tmp_str, NODE_MAX, "%d", saved_dcvs_cpu0_slack_min);
Anurag Singh6ec12062012-10-02 09:59:01 -0700485
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800486 if (sysfs_write(DCVS_CPU0_SLACK_MIN_NODE, tmp_str) != 0) {
487 if (!slack_node_rw_failed) {
488 ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MIN_NODE);
Anurag Singh6ec12062012-10-02 09:59:01 -0700489 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800490
491 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700492 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800493 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700494
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800495 if (saved_mpdecision_slack_max != -1) {
496 snprintf(tmp_str, NODE_MAX, "%d", saved_mpdecision_slack_max);
Anurag Singh6ec12062012-10-02 09:59:01 -0700497
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800498 if (sysfs_write(MPDECISION_SLACK_MAX_NODE, tmp_str) != 0) {
499 if (!slack_node_rw_failed) {
500 ALOGE("Failed to write to %s", MPDECISION_SLACK_MAX_NODE);
Anurag Singh6ec12062012-10-02 09:59:01 -0700501 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800502
503 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700504 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800505 }
Anurag Singh6ec12062012-10-02 09:59:01 -0700506
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800507 if (saved_mpdecision_slack_min != -1) {
508 snprintf(tmp_str, NODE_MAX, "%d", saved_mpdecision_slack_min);
Anurag Singh6ec12062012-10-02 09:59:01 -0700509
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800510 if (sysfs_write(MPDECISION_SLACK_MIN_NODE, tmp_str) != 0) {
511 if (!slack_node_rw_failed) {
512 ALOGE("Failed to write to %s", MPDECISION_SLACK_MIN_NODE);
Anurag Singh6ec12062012-10-02 09:59:01 -0700513 }
Zhao Wei Liew1e863522016-06-26 21:29:34 +0800514
515 rc = 1;
Anurag Singh6ec12062012-10-02 09:59:01 -0700516 }
517 }
518
519 slack_node_rw_failed = rc;
520 }
Anurag Singh6f64e9f2012-10-09 16:08:38 -0700521 }
Anurag Singh9cec85b2012-09-04 21:46:24 -0700522}
523
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700524void __attribute__((weak)) set_device_specific_feature(feature_t UNUSED(feature), int UNUSED(state))
Keith Mok964d2552015-11-13 09:46:14 -0800525{
526}
527
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700528void set_feature(feature_t feature, int state)
Steve Kondike4f15bd2015-10-19 14:43:39 -0700529{
530 switch (feature) {
531#ifdef TAP_TO_WAKE_NODE
532 case POWER_FEATURE_DOUBLE_TAP_TO_WAKE:
533 sysfs_write(TAP_TO_WAKE_NODE, state ? "1" : "0");
534 break;
535#endif
536 default:
537 break;
538 }
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700539 set_device_specific_feature(feature, state);
Steve Kondike4f15bd2015-10-19 14:43:39 -0700540}
541
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700542static int parse_stats(const char **params, size_t params_size,
543 uint64_t *list, FILE *fp) {
544 ssize_t nread;
545 size_t len = LINE_SIZE;
546 char *line;
547 size_t params_read = 0;
548 size_t i;
549 line = malloc(len);
550 if (!line) {
551 ALOGE("%s: no memory to hold line", __func__);
552 return -ENOMEM;
553 }
554 while ((params_read < params_size) &&
555 (nread = getline(&line, &len, fp) > 0)) {
556 char *key = line + strspn(line, " \t");
557 char *value = strchr(key, ':');
558 if (!value || (value > (line + len)))
559 continue;
560 *value++ = '\0';
561 for (i = 0; i < params_size; i++) {
562 if (!strcmp(key, params[i])) {
563 list[i] = strtoull(value, NULL, 0);
564 params_read++;
565 break;
Ananth Raghavan Subramanian65a6a062017-03-21 16:26:20 -0700566 }
567 }
568 }
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700569 free(line);
570 return 0;
Ananth Raghavan Subramanian65a6a062017-03-21 16:26:20 -0700571}
572
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200573#ifdef LEGACY_STATS
574static int extract_stats(uint64_t *list, char *file, const char**param_names,
575 unsigned int num_parameters, int isHex) {
576 FILE *fp;
577 ssize_t read;
578 size_t len;
579 size_t index = 0;
580 char *line;
581 int ret;
582
583 fp = fopen(file, "r");
584 if (fp == NULL) {
585 ret = -errno;
586 ALOGE("%s: failed to open: %s Error = %s", __func__, file, strerror(errno));
587 return ret;
588 }
589
590 for (line = NULL, len = 0;
591 ((read = getline(&line, &len, fp) != -1) && (index < num_parameters));
592 free(line), line = NULL, len = 0) {
593 uint64_t value;
594 char* offset;
595
596 size_t begin = strspn(line, " \t");
597 if (strncmp(line + begin, param_names[index], strlen(param_names[index]))) {
598 continue;
599 }
600
601 offset = memchr(line, ':', len);
602 if (!offset) {
603 continue;
604 }
605
606 if (isHex) {
607 sscanf(offset, ":%" SCNx64, &value);
608 } else {
609 sscanf(offset, ":%" SCNu64, &value);
610 }
611 list[index] = value;
612 index++;
613 }
614
615 free(line);
616 fclose(fp);
617
618 return 0;
619}
620
621int extract_platform_stats(uint64_t *list) {
622 int ret;
623 //Data is located in two files
624 ret = extract_stats(list, RPM_STAT, rpm_param_names, RPM_PARAM_COUNT, false);
625 if (ret) {
626 for (size_t i=0; i < RPM_PARAM_COUNT; i++)
627 list[i] = 0;
628 }
629 ret = extract_stats(list + RPM_PARAM_COUNT, RPM_MASTER_STAT,
630 rpm_master_param_names, PLATFORM_PARAM_COUNT - RPM_PARAM_COUNT, true);
631 if (ret) {
632 for (size_t i=RPM_PARAM_COUNT; i < PLATFORM_PARAM_COUNT; i++)
633 list[i] = 0;
634 }
635 return 0;
636}
637
638#ifndef V1_0_HAL
639int extract_wlan_stats(uint64_t *list) {
640 int ret;
Rashed Abdel-Tawab031a2bc2018-01-09 20:31:32 -0500641 ret = extract_stats(list, WLAN_POWER_STAT, wlan_param_names, WLAN_POWER_PARAMS_COUNT, false);
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200642 if (ret) {
Rashed Abdel-Tawab031a2bc2018-01-09 20:31:32 -0500643 for (size_t i=0; i < WLAN_POWER_PARAMS_COUNT; i++)
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200644 list[i] = 0;
645 }
646 return 0;
647}
648#endif
649#else
650
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700651static int extract_stats(uint64_t *list, char *file,
652 struct stat_pair *map, size_t map_size) {
653 FILE *fp;
654 ssize_t read;
655 size_t len = LINE_SIZE;
656 char *line;
657 size_t i, stats_read = 0;
658 int ret = 0;
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200659
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700660 fp = fopen(file, "re");
661 if (fp == NULL) {
662 ALOGE("%s: failed to open: %s Error = %s", __func__, file, strerror(errno));
663 return -errno;
664 }
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200665
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700666 line = malloc(len);
667 if (!line) {
668 ALOGE("%s: no memory to hold line", __func__);
669 fclose(fp);
670 return -ENOMEM;
671 }
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200672
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700673 while ((stats_read < map_size) && (read = getline(&line, &len, fp) != -1)) {
674 size_t begin = strspn(line, " \t");
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200675
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700676 for (i = 0; i < map_size; i++) {
677 if (!strncmp(line + begin, map[i].label, strlen(map[i].label))) {
678 stats_read++;
679 break;
680 }
681 }
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200682
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700683 if (i == map_size)
684 continue;
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200685
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700686 ret = parse_stats(map[i].parameters, map[i].num_parameters,
687 &list[map[i].stat * MAX_RPM_PARAMS], fp);
688 if (ret < 0)
689 break;
690 }
691 free(line);
692 fclose(fp);
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200693
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700694 return ret;
695}
Anurag Singh9cec85b2012-09-04 21:46:24 -0700696
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200697int extract_platform_stats(uint64_t *list) {
698 return extract_stats(list, RPM_SYSTEM_STAT, rpm_stat_map, ARRAY_SIZE(rpm_stat_map));
699}
700
701#ifndef V1_0_HAL
Rashed Abdel-Tawab711a28d2017-11-03 12:44:16 -0700702int extract_wlan_stats(uint64_t *list) {
703 return extract_stats(list, WLAN_POWER_STAT, wlan_stat_map, ARRAY_SIZE(wlan_stat_map));
704}
Rashed Abdel-Tawabe52ce102017-12-30 00:41:49 +0200705#endif
706#endif