blob: 0bec132982bad0bcea388158859760b4a75b26bb [file] [log] [blame]
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +05301/*
2 * Copyright (c) 2017, The Linux Foundation. All rights reserved.
Michael Bestas47636f62018-05-25 21:30:28 +03003 * Copyright (C) 2018 The LineageOS Project
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +05304 *
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
Michael Bestas1add9ac2018-03-25 22:56:44 +030041#define LOG_TAG "QCOM PowerHAL"
Ethan Chena42f4a82018-03-01 21:31:15 -080042#include <log/log.h>
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +053043#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
Nikhil Kumar Kansal839d56f2017-04-18 15:50:25 +053052#define MIN_VAL(X,Y) ((X>Y)?(Y):(X))
53
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +053054static int video_encode_hint_sent;
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +053055
dianlujitao93023a22018-09-06 17:45:43 +080056static int current_power_profile = PROFILE_BALANCED;
57
58static int profile_high_performance[] = {
59 ALL_CPUS_PWR_CLPS_DIS_V3, 0x1,
60 SCHED_BOOST_ON_V3, 0x1,
61 SCHED_MOSTLY_IDLE_NR_RUN, 0x1,
62 SCHED_SPILL_NR_RUN, 0x1,
63 SCHED_RESTRICT_CLUSTER_SPILL, 0x0,
64 SCHED_GROUP_DOWN_MIGRATE, 0x5F,
65 SCHED_GROUP_UP_MIGRATE, 0x64,
66 CPUS_ONLINE_MIN_BIG, 0x4,
67 MIN_FREQ_BIG_CORE_0, 0xFFF,
68 MIN_FREQ_LITTLE_CORE_0, 0xFFF,
69};
70
71static int profile_power_save[] = {
72 CPUS_ONLINE_MAX_BIG, 0x2,
73 MAX_FREQ_BIG_CORE_0, 0x0,
74 MAX_FREQ_LITTLE_CORE_0, 0x0,
75};
76
77static int profile_bias_power[] = {
78 CPUS_ONLINE_MAX_BIG, 0x2,
79 MAX_FREQ_BIG_CORE_0_RESIDX, 0x3,
80 MAX_FREQ_LITTLE_CORE_0_RESIDX, 0x1,
81};
82
83static int profile_bias_performance[] = {
84 MIN_FREQ_BIG_CORE_0_RESIDX, 0x3,
85 MIN_FREQ_LITTLE_CORE_0_RESIDX, 0x2,
86};
87
88#ifdef INTERACTION_BOOST
89int get_number_of_profiles()
90{
91 return 5;
92}
93#endif
94
95static int set_power_profile(int profile)
96{
97 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 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_power_save,
113 ARRAY_SIZE(profile_power_save));
114 profile_name = "powersave";
115
116 } else if (profile == PROFILE_HIGH_PERFORMANCE) {
117 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID,
118 profile_high_performance, ARRAY_SIZE(profile_high_performance));
119 profile_name = "performance";
120
121 } else if (profile == PROFILE_BIAS_POWER) {
122 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_bias_power,
123 ARRAY_SIZE(profile_bias_power));
124 profile_name = "bias power";
125
126 } else if (profile == PROFILE_BIAS_PERFORMANCE) {
127 ret = perform_hint_action(DEFAULT_PROFILE_HINT_ID,
128 profile_bias_performance, ARRAY_SIZE(profile_bias_performance));
129 profile_name = "bias perf";
130 } else if (profile == PROFILE_BALANCED) {
131 ret = 0;
132 profile_name = "balanced";
133 }
134
135 if (ret == 0) {
136 current_power_profile = profile;
137 ALOGD("%s: Set %s mode", __func__, profile_name);
138 }
139 return ret;
140}
141
Zhao Wei Liew6fe52522016-07-19 19:57:06 +0800142/**
Zhao Wei Liew143f8072018-11-02 00:33:14 +0000143 * Returns true if the target is SDM630.
Zhao Wei Liew6fe52522016-07-19 19:57:06 +0800144 */
145static bool is_target_SDM630(void)
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530146{
Zhao Wei Liew143f8072018-11-02 00:33:14 +0000147 static int is_SDM630 = -1;
Zhao Wei Liew6fe52522016-07-19 19:57:06 +0800148 int soc_id;
149
Zhao Wei Liew143f8072018-11-02 00:33:14 +0000150 if (is_SDM630 >= 0)
151 return is_SDM630;
152
Zhao Wei Liew6fe52522016-07-19 19:57:06 +0800153 soc_id = get_soc_id();
Zhao Wei Liew143f8072018-11-02 00:33:14 +0000154 is_SDM630 = soc_id == 318 || soc_id == 327;
Zhao Wei Liew6fe52522016-07-19 19:57:06 +0800155
156 return is_SDM630;
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530157}
158
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530159static void process_video_encode_hint(void *metadata)
160{
161 char governor[80];
162 int resource_values[20];
163 int num_resources;
164 struct video_encode_metadata_t video_encode_metadata;
165
Michael Bestas47636f62018-05-25 21:30:28 +0300166 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU0) == -1) {
167 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU1) == -1) {
168 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU2) == -1) {
169 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU3) == -1) {
170 ALOGE("Can't obtain scaling governor.");
171 return;
172 }
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530173 }
Michael Bestas47636f62018-05-25 21:30:28 +0300174 }
175 }
176
177 if (!metadata) {
178 return;
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530179 }
180
181 /* Initialize encode metadata struct fields. */
182 memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t));
183 video_encode_metadata.state = -1;
184 video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID;
185
Michael Bestas47636f62018-05-25 21:30:28 +0300186 if (parse_video_encode_metadata((char *)metadata,
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530187 &video_encode_metadata) == -1) {
Michael Bestas47636f62018-05-25 21:30:28 +0300188 ALOGE("Error occurred while parsing metadata.");
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530189 return;
190 }
191
192 if (video_encode_metadata.state == 1) {
Ethan Chen4b4acdf2018-03-01 21:41:04 -0800193 if (is_interactive_governor(governor)) {
Michael Bestas47636f62018-05-25 21:30:28 +0300194 if (is_target_SDM630()) {
195 /*
196 1. CPUfreq params
197 - hispeed freq for big - 1113Mhz
198 - go hispeed load for big - 95
199 - above_hispeed_delay for big - 40ms
200 - target loads - 95
201 - nr_run - 5
202 2. BusDCVS V2 params
203 - Sample_ms of 10ms
204 */
205 int res[] = {
206 HISPEED_FREQ_BIG, 0x459,
207 GO_HISPEED_LOAD_BIG, 0x5F,
208 ABOVE_HISPEED_DELAY_BIG, 0x4,
209 TARGET_LOADS_BIG, 0x5F,
dianlujitao5eb472d2018-09-06 21:43:14 +0800210 SCHED_SPILL_NR_RUN, 0X5,
Michael Bestas47636f62018-05-25 21:30:28 +0300211 CPUBW_HWMON_SAMPLE_MS, 0xA
212 };
Nikhil Kumar Kansal839d56f2017-04-18 15:50:25 +0530213 memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res)));
Zhao Wei Liewd4fe61e2016-06-26 11:37:59 +0800214 num_resources = ARRAY_SIZE(res);
Michael Bestas47636f62018-05-25 21:30:28 +0300215 } else {
216 /*
217 1. CPUfreq params
218 - hispeed freq for little - 902Mhz
219 - go hispeed load for little - 95
220 - above_hispeed_delay for little - 40ms
221 2. BusDCVS V2 params
222 - Sample_ms of 10ms
223 */
224 int res[] = {
225 HISPEED_FREQ_LITTLE, 0x386,
226 GO_HISPEED_LOAD_LITTLE, 0x5F,
227 ABOVE_HISPEED_DELAY_LITTLE, 0x4,
228 CPUBW_HWMON_SAMPLE_MS, 0xA
229 };
Nikhil Kumar Kansal839d56f2017-04-18 15:50:25 +0530230 memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res)));
Zhao Wei Liewd4fe61e2016-06-26 11:37:59 +0800231 num_resources = ARRAY_SIZE(res);
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530232 }
Michael Bestas50a6e282018-05-25 21:33:46 +0300233 if (!video_encode_hint_sent) {
234 perform_hint_action(video_encode_metadata.hint_id,
235 resource_values, num_resources);
236 video_encode_hint_sent = 1;
237 }
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530238 }
239 } else if (video_encode_metadata.state == 0) {
Ethan Chen4b4acdf2018-03-01 21:41:04 -0800240 if (is_interactive_governor(governor)) {
Michael Bestas50a6e282018-05-25 21:33:46 +0300241 undo_hint_action(video_encode_metadata.hint_id);
242 video_encode_hint_sent = 0;
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530243 }
244 }
Michael Bestas47636f62018-05-25 21:30:28 +0300245}
246
247int power_hint_override(power_hint_t hint, void *data)
248{
dianlujitao93023a22018-09-06 17:45:43 +0800249 if (hint == POWER_HINT_SET_PROFILE) {
250 if (set_power_profile(*(int32_t *)data) < 0)
251 ALOGE("Setting power profile failed. perf HAL not started?");
252 return HINT_HANDLED;
253 }
254
255 // Skip other hints in high/low power modes
256 if (current_power_profile == PROFILE_POWER_SAVE ||
257 current_power_profile == PROFILE_HIGH_PERFORMANCE) {
258 return HINT_HANDLED;
259 }
260
Michael Bestas47636f62018-05-25 21:30:28 +0300261 switch (hint) {
262 case POWER_HINT_VSYNC:
263 break;
264 case POWER_HINT_VIDEO_ENCODE:
265 process_video_encode_hint(data);
266 return HINT_HANDLED;
267 default:
268 break;
269 }
270 return HINT_NONE;
271}
272
273int set_interactive_override(int on)
274{
275 char governor[80];
276 int resource_values[20];
277 int num_resources;
278
279 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU0) == -1) {
280 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU1) == -1) {
281 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU2) == -1) {
282 if (get_scaling_governor_check_cores(governor, sizeof(governor), CPU3) == -1) {
283 ALOGE("Can't obtain scaling governor.");
284 return HINT_NONE;
285 }
286 }
287 }
288 }
289
290 if (!on) {
291 /* Display off. */
292 if (is_interactive_governor(governor)) {
293 if (is_target_SDM630()) {
294 /*
295 1. CPUfreq params
296 - hispeed freq for big - 1113Mhz
297 - go hispeed load for big - 95
298 - above_hispeed_delay for big - 40ms
299 2. BusDCVS V2 params
300 - Sample_ms of 10ms
301 */
302 int res[] = {
303 HISPEED_FREQ_BIG, 0x459,
304 GO_HISPEED_LOAD_BIG, 0x5F,
305 ABOVE_HISPEED_DELAY_BIG, 0x4,
306 CPUBW_HWMON_SAMPLE_MS, 0xA
307 };
308 memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res)));
309 num_resources = ARRAY_SIZE(res);
310 } else {
311 /*
312 1. CPUfreq params
313 - hispeed freq for little - 902Mhz
314 - go hispeed load for little - 95
315 - above_hispeed_delay for little - 40ms
316 2. BusDCVS V2 params
317 - Sample_ms of 10ms
318 3. Sched group upmigrate - 500
319 */
320 int res[] = {
321 HISPEED_FREQ_LITTLE, 0x386,
322 GO_HISPEED_LOAD_LITTLE, 0x5F,
323 ABOVE_HISPEED_DELAY_LITTLE, 0x4,
324 CPUBW_HWMON_SAMPLE_MS, 0xA,
325 SCHED_GROUP_UP_MIGRATE, 0x1F4
326 };
327 memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res)));
328 num_resources = ARRAY_SIZE(res);
329
330 }
331 perform_hint_action(DISPLAY_STATE_HINT_ID,
332 resource_values, num_resources);
333 }
334 } else {
335 /* Display on. */
336 if (is_interactive_governor(governor)) {
337 undo_hint_action(DISPLAY_STATE_HINT_ID);
338 }
339 }
340 return HINT_HANDLED;
Vara Prasad A V S G9b7a7582017-04-07 17:32:37 +0530341}