blob: 495e1964ef7ecae1ba22fc3425a851346fb30b4d [file] [log] [blame]
Zhao Wei Liew11eedda2015-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
94static int set_power_profile(int profile)
95{
96 int ret = -EINVAL;
97 const char *profile_name = NULL;
98
99 if (profile == current_power_profile)
100 return 0;
101
102 ALOGV("%s: Profile=%d", __func__, profile);
103
104 if (current_power_profile != PROFILE_BALANCED) {
105 undo_hint_action(DEFAULT_PROFILE_HINT_ID);
106 ALOGV("%s: Hint undone", __func__);
107 current_power_profile = PROFILE_BALANCED;
108 }
109
110 if (profile == PROFILE_POWER_SAVE) {
111 int* resource_values = is_target_8064() ?
112 profile_power_save_8064 : profile_power_save_8960;
113
114 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID,
115 resource_values, ARRAY_SIZE(resource_values));
116 profile_name = "powersave";
117
118 } else if (profile == PROFILE_HIGH_PERFORMANCE) {
119 int *resource_values = is_target_8064() ?
120 profile_high_performance_8064 : profile_high_performance_8960;
121
122 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID,
123 resource_values, ARRAY_SIZE(resource_values));
124 profile_name = "performance";
125
126 } else if (profile == PROFILE_BALANCED) {
127 ret = 0;
128 profile_name = "balanced";
129 }
130
131 if (ret == 0) {
132 current_power_profile = profile;
133 ALOGD("%s: Set %s mode", __func__, profile_name);
134 }
135 return ret;
136}
137
138int power_hint_override(power_hint_t hint, void *data)
139{
140 if (hint == POWER_HINT_SET_PROFILE) {
141 if (set_power_profile(*(int32_t *)data) < 0)
142 ALOGE("Setting power profile failed. perfd not started?");
143 return HINT_HANDLED;
144 }
145
146 // Skip other hints in high/low power modes
147 if (current_power_profile == PROFILE_POWER_SAVE ||
148 current_power_profile == PROFILE_HIGH_PERFORMANCE) {
149 return HINT_HANDLED;
150 }
151
152 return HINT_NONE;
153}