summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2019-10-06 04:16:15 +0300
committerMichael Bestas <mkbestas@lineageos.org>2019-10-23 01:12:57 +0300
commit919a6ad95009492ac96b11cb1bf50ae22e7c2d6b (patch)
tree004a109aea48ab59e43f3d046a99e5349aedf2cf
parentef7a7ed7e04d113afdbe96ca07f55dd74111cc3c (diff)
downloadvendor_qcom_opensource_power-919a6ad95009492ac96b11cb1bf50ae22e7c2d6b.zip
vendor_qcom_opensource_power-919a6ad95009492ac96b11cb1bf50ae22e7c2d6b.tar.gz
vendor_qcom_opensource_power-919a6ad95009492ac96b11cb1bf50ae22e7c2d6b.tar.bz2
power: Handle launch and interaction hints for legacy platforms
Author: Michael Bestas <mkbestas@lineageos.org> Date: Mon Mar 26 01:52:03 2018 +0300 power: apq8084: Add support for power profile & boost * Based on msm8974 HAL. Change-Id: I88ce707b022f7b122ad7a2fcfc67fde0075d7e7a Author: Michael Bestas <mkbestas@lineageos.org> Date: Mon Mar 26 02:07:03 2018 +0300 power: msm8226: Add support for power profile & boost * Based on legacy HAL implementation Change-Id: Ifb93945e4e4005ef922cacee95e51bb95d5df9e3 Author: Michael Bestas <mkbestas@lineageos.org> Date: Mon Mar 26 02:13:51 2018 +0300 power: msm8610: Add support for power profile & boost * Based on legacy HAL implementation Change-Id: If778938b9703fd01185c2448bc83a09f04348333 Author: dianlujitao <dianlujitao@lineageos.org> Date: Sun Mar 25 18:08:45 2018 +0800 power: msm8916: Add support for power profile & boost * Based on legacy HAL implementation Change-Id: I20225ae9244023555724c76df5e208fd60eb3841 Author: Michael Bestas <mkbestas@lineageos.org> Date: Mon Jan 22 02:30:25 2018 +0200 power: msm8974: Add support for power profile * Based on Steve Kondik's and Zhao Wei Liew's implementation from the legacy HAL. Change-Id: Ie2a28b589537349cbcefc5b64e5404d346edf2c2 Author: Michael Bestas <mkbestas@lineageos.org> Date: Mon Mar 26 03:24:26 2018 +0300 power: msm8974: POWER_HINT_INTERACTION improvements Change-Id: I9bde2a1d62fcb9e987741b5932f8f50a019cdfd2 Author: Craig Tatlor <ctatlor97@gmail.com> Date: Mon May 21 17:22:31 2018 +0100 power: msm8974: Build with with BOARD_VNDK_VERSION time.h isnt included by default when vndk is enabled. Change-Id: I7ca6ca601a8d25557bd1bb0484766121a9ae5633 Author: Michael Bestas <mkbestas@lineageos.org> Date: Mon Mar 26 03:00:15 2018 +0300 power: msm8992: Add support for power profile & boost * Based on legacy HAL implementation Change-Id: I9ebb44c1e215a76a95180a6188e80cb24f0b03ba Author: Michael Bestas <mkbestas@lineageos.org> Date: Mon Mar 26 03:00:30 2018 +0300 power: msm8994: Add support for power profile & boost * Based on legacy HAL implementation Change-Id: I5aa0b75b493825f2d87ce6eea0f3c3b1c3bba135 Author: Michael Bestas <mkbestas@lineageos.org> Date: Fri May 25 21:30:28 2018 +0300 power: Spring cleanup * Cleanup SoC specific files: - Fix code spacing and indentation - Remove dead code - Remove useless comments - Remove useless logs - Make code uniform between the files so it's easier to diff - Use declared enums when possible for power hints Change-Id: Ie1378c94c53b33299927c5eb1bfc19f1a42b8743 Author: Corinna Vinschen <xda@vinschen.de> Date: Mon Aug 6 21:14:12 2018 +0200 power-8084: clean up code * express interactive boost frequencies as descriptive symbolic values rather than arbitrary hex numbers * express durations as descriptive symbolic values rather than just numbers in the code Change-Id: I47a92bd4c9b0b86ae0444d87345daf4e94d56126 Signed-off-by: Corinna Vinschen <xda@vinschen.de> Author: Corinna Vinschen <xda@vinschen.de> Date: Mon Aug 6 10:58:20 2018 +0200 power-8084: reduce interactive boost * 1,1 GHz min freq is more than enough for interactive boost on apq8084 * default duration is unnecessarily long, reduce to 200 ms * 1,5 GHz min freq on 2 CPUs for 1 sec is entirely sufficient for launch action Change-Id: I5e51267ed32a3e50899627e4281321820fac237f Signed-off-by: Corinna Vinschen <xda@vinschen.de> Author: Corinna Vinschen <xda@vinschen.de> Date: Mon Aug 6 16:52:08 2018 +0200 power-8084: drop POWER_HINT_LAUNCH handling * kernel governor is doing well by itself, but thanks all the same Change-Id: I64fa61a1d8ff0f20bac9e5c32c56b031570a564f Signed-off-by: Corinna Vinschen <xda@vinschen.de> Author: Corinna Vinschen <xda@vinschen.de> Date: Fri Oct 12 21:40:24 2018 +0200 power-8084: Revert POWER_HINT_LAUNCH handling This effectively reverts commit 0ef4cb429ff3d42e8f8bd27d749ecd80f2911dc5. Users (including myself) noticed some laggy behaviour. The patch reverts to some more oomph at launch time, trying for a compromise between performance and power saving. Change-Id: I2d07686a131dcb75c9e590d99764d2a650cae507 Author: Craig Tatlor <ctatlor97@gmail.com> Date: Mon May 21 17:22:31 2018 +0100 power: Build with with BOARD_VNDK_VERSION time.h isnt included by default when vndk is enabled. Change-Id: I949ed271d7e7ed31e186019b0289299c1c8ff940 Author: tomascus <arbiter1000@gmail.com> Date: Tue Feb 19 17:15:58 2019 +1100 power: Release launch boost perflock when launch is completed Currently, the launch boost perflock is held for a fixed duration, either specified in perfboostsconfig.xml for perf HAL platforms or hardcoded in the powerHAL for non-perf HAL platforms. Using a fixed duration for this perflock has two shortcomings: * perflock can be held for too long, causing the CPU freq and other resources to be boosted for too long even if the application has finished launching, resulting in excessive battery drainage * perflock can be held not long enough if it takes more than the timeout time to finish launch The framework sends out a powerhint for both when launch starts and when launch ends. The launch finish hint can be used to signal when to release the perflock. Reference: Wahoo power-libperfmgr Change-Id: I405cc453c5f58d9fb2583b9c6017f3964a0ce024 Change-Id: I8a1d8101bc40d3fc169a0f1f2982a5cac76e6a13
-rw-r--r--power-8084.c102
-rw-r--r--power-8226.c46
-rw-r--r--power-8610.c46
-rw-r--r--power-8916.c116
-rw-r--r--power-8974.c99
-rw-r--r--power-8992.c91
-rw-r--r--power-8994.c91
7 files changed, 571 insertions, 20 deletions
diff --git a/power-8084.c b/power-8084.c
index 8612769..4ed01a7 100644
--- a/power-8084.c
+++ b/power-8084.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -125,6 +126,100 @@ static int process_video_decode_hint(void* metadata) {
return HINT_NONE;
}
+// clang-format off
+/* fling boost: min 3 CPUs, min 1.1 GHz */
+static int resources_interaction_fling_boost[] = {
+ CPUS_ONLINE_MIN_3,
+ CPU0_MIN_FREQ_NONTURBO_MAX + 1,
+ CPU1_MIN_FREQ_NONTURBO_MAX + 1,
+ CPU2_MIN_FREQ_NONTURBO_MAX + 1,
+ CPU3_MIN_FREQ_NONTURBO_MAX + 1
+};
+
+/* interactive boost: min 2 CPUs, min 1.1 GHz */
+static int resources_interaction_boost[] = {
+ CPUS_ONLINE_MIN_2,
+ CPU0_MIN_FREQ_NONTURBO_MAX + 1,
+ CPU1_MIN_FREQ_NONTURBO_MAX + 1,
+ CPU2_MIN_FREQ_NONTURBO_MAX + 1,
+ CPU3_MIN_FREQ_NONTURBO_MAX + 1
+};
+
+/* lauch boost: min 2 CPUs, full power for 2 CPUs, min 1.5 GHz for the others */
+static int resources_launch[] = {
+ CPUS_ONLINE_MIN_2,
+ CPU0_MIN_FREQ_TURBO_MAX,
+ CPU1_MIN_FREQ_TURBO_MAX,
+ CPU2_MIN_FREQ_NONTURBO_MAX + 5,
+ CPU3_MIN_FREQ_NONTURBO_MAX + 5
+};
+// clang-format on
+
+const int kDefaultInteractiveDuration = 200; /* ms */
+const int kMinFlingDuration = 1500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kDefaultInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ if (duration >= kMinFlingDuration) {
+ interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost),
+ resources_interaction_fling_boost);
+ } else {
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost);
+ }
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (!launch_mode) {
+ launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration,
+ ARRAY_SIZE(resources_launch), resources_launch);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -134,6 +229,13 @@ int power_hint_override(power_hint_t hint, void* data) {
case POWER_HINT_VIDEO_DECODE:
ret_val = process_video_decode_hint(data);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-8226.c b/power-8226.c
index b654923..7f5ff72 100644
--- a/power-8226.c
+++ b/power-8226.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -123,6 +124,46 @@ static int process_video_decode_hint(void* metadata) {
return HINT_NONE;
}
+// clang-format off
+static int resources_interaction_boost[] = {
+ CPUS_ONLINE_MIN_2,
+ 0x20B,
+ 0x30B
+};
+// clang-format on
+
+const int kDefaultInteractiveDuration = 500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kDefaultInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost);
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -133,10 +174,7 @@ int power_hint_override(power_hint_t hint, void* data) {
ret_val = process_video_decode_hint(data);
break;
case POWER_HINT_INTERACTION:
- int resources[] = {CPUS_ONLINE_MIN_2, 0x20B, 0x30B};
- int duration = 3000;
-
- interaction(duration, ARRAY_SIZE(resources), resources);
+ process_interaction_hint(data);
ret_val = HINT_HANDLED;
break;
default:
diff --git a/power-8610.c b/power-8610.c
index b654923..7f5ff72 100644
--- a/power-8610.c
+++ b/power-8610.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -123,6 +124,46 @@ static int process_video_decode_hint(void* metadata) {
return HINT_NONE;
}
+// clang-format off
+static int resources_interaction_boost[] = {
+ CPUS_ONLINE_MIN_2,
+ 0x20B,
+ 0x30B
+};
+// clang-format on
+
+const int kDefaultInteractiveDuration = 500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kDefaultInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost);
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -133,10 +174,7 @@ int power_hint_override(power_hint_t hint, void* data) {
ret_val = process_video_decode_hint(data);
break;
case POWER_HINT_INTERACTION:
- int resources[] = {CPUS_ONLINE_MIN_2, 0x20B, 0x30B};
- int duration = 3000;
-
- interaction(duration, ARRAY_SIZE(resources), resources);
+ process_interaction_hint(data);
ret_val = HINT_HANDLED;
break;
default:
diff --git a/power-8916.c b/power-8916.c
index 25011bc..fedda05 100644
--- a/power-8916.c
+++ b/power-8916.c
@@ -36,6 +36,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -71,23 +72,114 @@ static bool is_target_8916(void) {
return is_8916;
}
-int power_hint_override(power_hint_t hint, void* UNUSED(data)) {
- switch (hint) {
- case POWER_HINT_VSYNC:
- break;
- case POWER_HINT_INTERACTION: {
- int resources[] = {CPUS_ONLINE_MIN_2, 0x20F, 0x30F};
- int duration = 3000;
+// clang-format off
+static int resources_interaction_fling_boost[] = {
+ ALL_CPUS_PWR_CLPS_DIS,
+ SCHED_BOOST_ON,
+ SCHED_PREFER_IDLE_DIS,
+ 0x20D
+};
+
+static int resources_interaction_boost[] = {
+ ALL_CPUS_PWR_CLPS_DIS,
+ SCHED_PREFER_IDLE_DIS,
+ 0x20D
+};
+
+static int resources_launch[] = {
+ ALL_CPUS_PWR_CLPS_DIS,
+ SCHED_BOOST_ON,
+ SCHED_PREFER_IDLE_DIS,
+ 0x20F,
+ 0x1C00,
+ 0x4001,
+ 0x4101,
+ 0x4201
+};
+// clang-format on
+
+const int kDefaultInteractiveDuration = 500; /* ms */
+const int kMinFlingDuration = 1500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kDefaultInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ if (duration >= kMinFlingDuration) {
+ interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost),
+ resources_interaction_fling_boost);
+ } else {
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost);
+ }
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
- interaction(duration, ARRAY_SIZE(resources), resources);
- return HINT_HANDLED;
+ if (!launch_mode) {
+ launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration,
+ ARRAY_SIZE(resources_launch), resources_launch);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
}
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
+int power_hint_override(power_hint_t hint, void* data) {
+ int ret_val = HINT_NONE;
+ switch (hint) {
case POWER_HINT_VIDEO_ENCODE: /* Do nothing for encode case */
- return HINT_HANDLED;
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
- return HINT_HANDLED;
+ break;
}
- return HINT_NONE;
+ return ret_val;
}
int set_interactive_override(int on) {
diff --git a/power-8974.c b/power-8974.c
index e5ddf0f..9b9a52d 100644
--- a/power-8974.c
+++ b/power-8974.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -140,6 +141,97 @@ static int process_video_decode_hint(void* metadata) {
return HINT_NONE;
}
+// clang-format off
+static int resources_interaction_fling_boost[] = {
+ CPUS_ONLINE_MIN_3,
+ 0x20F,
+ 0x30F,
+ 0x40F,
+ 0x50F
+};
+
+static int resources_interaction_boost[] = {
+ CPUS_ONLINE_MIN_2,
+ 0x20F,
+ 0x30F,
+ 0x40F,
+ 0x50F
+};
+
+static int resources_launch[] = {
+ CPUS_ONLINE_MIN_3,
+ CPU0_MIN_FREQ_TURBO_MAX,
+ CPU1_MIN_FREQ_TURBO_MAX,
+ CPU2_MIN_FREQ_TURBO_MAX,
+ CPU3_MIN_FREQ_TURBO_MAX
+};
+// clang-format on
+
+const int kDefaultInteractiveDuration = 500; /* ms */
+const int kMinFlingDuration = 1500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kDefaultInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ if (duration >= kMinFlingDuration) {
+ interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost),
+ resources_interaction_fling_boost);
+ } else {
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost);
+ }
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (!launch_mode) {
+ launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration,
+ ARRAY_SIZE(resources_launch), resources_launch);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -149,6 +241,13 @@ int power_hint_override(power_hint_t hint, void* data) {
case POWER_HINT_VIDEO_DECODE:
ret_val = process_video_decode_hint(data);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-8992.c b/power-8992.c
index b102017..6fc62d3 100644
--- a/power-8992.c
+++ b/power-8992.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -128,6 +129,89 @@ static int process_video_decode_hint(void* metadata) {
return HINT_NONE;
}
+// clang-format off
+static int resources_interaction_fling_boost[] = {
+ ALL_CPUS_PWR_CLPS_DIS,
+ SCHED_BOOST_ON,
+ SCHED_PREFER_IDLE_DIS
+};
+
+static int resources_interaction_boost[] = {
+ ALL_CPUS_PWR_CLPS_DIS,
+ SCHED_PREFER_IDLE_DIS
+};
+
+static int resources_launch[] = {
+ SCHED_BOOST_ON,
+ 0x20C
+};
+// clang-format on
+
+const int kDefaultInteractiveDuration = 500; /* ms */
+const int kMinFlingDuration = 1500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kDefaultInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ if (duration >= kMinFlingDuration) {
+ interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost),
+ resources_interaction_fling_boost);
+ } else {
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost);
+ }
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (!launch_mode) {
+ launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration,
+ ARRAY_SIZE(resources_launch), resources_launch);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -137,6 +221,13 @@ int power_hint_override(power_hint_t hint, void* data) {
case POWER_HINT_VIDEO_DECODE:
ret_val = process_video_decode_hint(data);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}
diff --git a/power-8994.c b/power-8994.c
index f51b782..ccc025a 100644
--- a/power-8994.c
+++ b/power-8994.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <time.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
@@ -128,6 +129,89 @@ static int process_video_decode_hint(void* metadata) {
return HINT_NONE;
}
+// clang-format off
+static int resources_interaction_fling_boost[] = {
+ ALL_CPUS_PWR_CLPS_DIS,
+ SCHED_BOOST_ON,
+ SCHED_PREFER_IDLE_DIS
+};
+
+static int resources_interaction_boost[] = {
+ ALL_CPUS_PWR_CLPS_DIS,
+ SCHED_PREFER_IDLE_DIS
+};
+
+static int resources_launch[] = {
+ SCHED_BOOST_ON,
+ 0x20C
+};
+// clang-format on
+
+const int kDefaultInteractiveDuration = 500; /* ms */
+const int kMinFlingDuration = 1500; /* ms */
+const int kMaxInteractiveDuration = 5000; /* ms */
+const int kMaxLaunchDuration = 5000; /* ms */
+
+static void process_interaction_hint(void* data) {
+ static struct timespec s_previous_boost_timespec;
+ static int s_previous_duration = 0;
+
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ int duration = kDefaultInteractiveDuration;
+
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration
+ : input_duration;
+ }
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
+
+ elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
+ // don't hint if previous hint's duration covers this hint's duration
+ if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
+ return;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
+
+ if (duration >= kMinFlingDuration) {
+ interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost),
+ resources_interaction_fling_boost);
+ } else {
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost);
+ }
+}
+
+static int process_activity_launch_hint(void* data) {
+ static int launch_handle = -1;
+ static int launch_mode = 0;
+
+ // release lock early if launch has finished
+ if (!data) {
+ if (CHECK_HANDLE(launch_handle)) {
+ release_request(launch_handle);
+ launch_handle = -1;
+ }
+ launch_mode = 0;
+ return HINT_HANDLED;
+ }
+
+ if (!launch_mode) {
+ launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration,
+ ARRAY_SIZE(resources_launch), resources_launch);
+ if (!CHECK_HANDLE(launch_handle)) {
+ ALOGE("Failed to perform launch boost");
+ return HINT_NONE;
+ }
+ launch_mode = 1;
+ }
+ return HINT_HANDLED;
+}
+
int power_hint_override(power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
@@ -137,6 +221,13 @@ int power_hint_override(power_hint_t hint, void* data) {
case POWER_HINT_VIDEO_DECODE:
ret_val = process_video_decode_hint(data);
break;
+ case POWER_HINT_INTERACTION:
+ process_interaction_hint(data);
+ ret_val = HINT_HANDLED;
+ break;
+ case POWER_HINT_LAUNCH:
+ ret_val = process_activity_launch_hint(data);
+ break;
default:
break;
}