blob: 0076cbb143b6b84aae4a3c7aeb298c7ef6d12b21 [file] [log] [blame]
Zhao Wei Liewfbb85212015-11-17 17:45:03 +08001/*
2 * Copyright (c) 2013, The Linux Foundation. All rights reserved.
3 * Copyright (C) 2018 The LineageOS Project
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 * * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
14 * * Neither the name of The Linux Foundation nor the names of its
15 * contributors may be used to endorse or promote products derived
16 * from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#define LOG_NIDEBUG 0
32
33#include <errno.h>
34#include <string.h>
35#include <sys/types.h>
36#include <sys/stat.h>
37#include <fcntl.h>
38#include <dlfcn.h>
39#include <stdlib.h>
40
41#define LOG_TAG "QCOM PowerHAL"
42#include <log/log.h>
43#include <hardware/hardware.h>
44#include <hardware/power.h>
45
46#include "utils.h"
47#include "metadata-defs.h"
48#include "hint-data.h"
49#include "performance.h"
50#include "power-common.h"
51
52/**
53 * Returns true if the target is APQ8064.
54 */
55static bool is_target_8064(void)
56{
57 static int is_8064 = -1;
58 int soc_id;
59
60 if (is_8064 >= 0)
61 return is_8064;
62
63 soc_id = get_soc_id();
64 is_8064 = soc_id == 153;
65
66 return is_8064;
67}
68
69static int current_power_profile = PROFILE_BALANCED;
70
71static int profile_high_performance_8960[] = {
72 CPUS_ONLINE_MIN_2,
73};
74
75static int profile_high_performance_8064[] = {
76 CPUS_ONLINE_MIN_4,
77};
78
79static int profile_power_save_8960[] = {
80 /* Don't do anything for now */
81};
82
83static int profile_power_save_8064[] = {
84 CPUS_ONLINE_MAX_LIMIT_2,
85};
86
87#ifdef INTERACTION_BOOST
88int get_number_of_profiles()
89{
90 return 3;
91}
92#endif
93
dianlujitao8780cb72019-02-23 20:24:57 +080094static int set_power_profile(void *data)
Zhao Wei Liewfbb85212015-11-17 17:45:03 +080095{
dianlujitao8780cb72019-02-23 20:24:57 +080096 int profile = data ? *((int*)data) : 0;
Zhao Wei Liewfbb85212015-11-17 17:45:03 +080097 int ret = -EINVAL;
98 const char *profile_name = NULL;
99
100 if (profile == current_power_profile)
101 return 0;
102
103 ALOGV("%s: Profile=%d", __func__, profile);
104
105 if (current_power_profile != PROFILE_BALANCED) {
106 undo_hint_action(DEFAULT_PROFILE_HINT_ID);
107 ALOGV("%s: Hint undone", __func__);
108 current_power_profile = PROFILE_BALANCED;
109 }
110
111 if (profile == PROFILE_POWER_SAVE) {
112 int* resource_values = is_target_8064() ?
113 profile_power_save_8064 : profile_power_save_8960;
114
115 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID,
116 resource_values, ARRAY_SIZE(resource_values));
117 profile_name = "powersave";
118
119 } else if (profile == PROFILE_HIGH_PERFORMANCE) {
120 int *resource_values = is_target_8064() ?
121 profile_high_performance_8064 : profile_high_performance_8960;
122
123 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID,
124 resource_values, ARRAY_SIZE(resource_values));
125 profile_name = "performance";
126
127 } else if (profile == PROFILE_BALANCED) {
128 ret = 0;
129 profile_name = "balanced";
130 }
131
132 if (ret == 0) {
133 current_power_profile = profile;
134 ALOGD("%s: Set %s mode", __func__, profile_name);
135 }
136 return ret;
137}
138
139int power_hint_override(power_hint_t hint, void *data)
140{
141 if (hint == POWER_HINT_SET_PROFILE) {
dianlujitao8780cb72019-02-23 20:24:57 +0800142 if (set_power_profile(data) < 0)
Zhao Wei Liewfbb85212015-11-17 17:45:03 +0800143 ALOGE("Setting power profile failed. perfd not started?");
144 return HINT_HANDLED;
145 }
146
147 // Skip other hints in high/low power modes
148 if (current_power_profile == PROFILE_POWER_SAVE ||
149 current_power_profile == PROFILE_HIGH_PERFORMANCE) {
150 return HINT_HANDLED;
151 }
152
153 return HINT_NONE;
154}