summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Bestas <mkbestas@lineageos.org>2018-03-26 02:13:51 +0300
committerMichael Bestas <mkbestas@lineageos.org>2018-04-16 16:16:22 +0300
commitce25d84762334a65439f0f077e8803192473f48a (patch)
tree9cd21c44dc41fee24f00a81873bc63beb9fc2a8d
parentdbc67818acc9022c02aeb2e28e1229264340c0a0 (diff)
downloadandroid_hardware_qcom_power-ce25d84762334a65439f0f077e8803192473f48a.tar.gz
android_hardware_qcom_power-ce25d84762334a65439f0f077e8803192473f48a.tar.bz2
android_hardware_qcom_power-ce25d84762334a65439f0f077e8803192473f48a.zip
power: msm8610: Add support for power profile & boost
* Based on legacy HAL implementation Change-Id: If778938b9703fd01185c2448bc83a09f04348333
-rw-r--r--power-8610.c97
1 files changed, 93 insertions, 4 deletions
diff --git a/power-8610.c b/power-8610.c
index 764d9cd..b0313df 100644
--- a/power-8610.c
+++ b/power-8610.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2018 The LineageOS Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -47,17 +48,105 @@
#include "performance.h"
#include "power-common.h"
+static int current_power_profile = PROFILE_BALANCED;
+
+static int profile_high_performance[] = {
+ CPUS_ONLINE_MIN_2,
+ CPU0_MIN_FREQ_TURBO_MAX,
+ CPU1_MIN_FREQ_TURBO_MAX
+};
+
+static int profile_power_save[] = {
+ CPUS_ONLINE_MAX_LIMIT_2,
+ CPU0_MAX_FREQ_NONTURBO_MAX,
+ CPU1_MAX_FREQ_NONTURBO_MAX
+};
+
+#ifdef INTERACTION_BOOST
+int get_number_of_profiles() {
+ return 3;
+}
+#endif
+
+static void set_power_profile(int profile) {
+
+ if (profile == current_power_profile)
+ return;
+
+ ALOGV("%s: Profile=%d", __func__, profile);
+
+ if (current_power_profile != PROFILE_BALANCED) {
+ undo_hint_action(DEFAULT_PROFILE_HINT_ID);
+ ALOGV("%s: Hint undone", __func__);
+ }
+
+ if (profile == PROFILE_POWER_SAVE) {
+ perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_power_save,
+ ARRAY_SIZE(profile_power_save));
+ ALOGD("%s: Set powersave mode", __func__);
+
+ } else if (profile == PROFILE_HIGH_PERFORMANCE) {
+ perform_hint_action(DEFAULT_PROFILE_HINT_ID, profile_high_performance,
+ ARRAY_SIZE(profile_high_performance));
+ ALOGD("%s: Set performance mode", __func__);
+
+ }
+
+ current_power_profile = profile;
+}
+
+static int resources_interaction_boost[] = {
+ CPUS_ONLINE_MIN_2,
+ 0x20B,
+ 0x30B
+};
+
int power_hint_override(power_hint_t hint, void *data)
{
- switch(hint) {
+ static struct timespec s_previous_boost_timespec;
+ struct timespec cur_boost_timespec;
+ long long elapsed_time;
+ static int s_previous_duration = 0;
+ int duration;
+
+ if (hint == POWER_HINT_SET_PROFILE) {
+ set_power_profile(*(int32_t *)data);
+ return HINT_HANDLED;
+ }
+
+ // Skip other hints in high/low power modes
+ if (current_power_profile == PROFILE_POWER_SAVE ||
+ current_power_profile == PROFILE_HIGH_PERFORMANCE) {
+ return HINT_HANDLED;
+ }
+
+ switch (hint) {
case POWER_HINT_INTERACTION:
{
- int resources[] = {0x702, 0x20B, 0x30B};
- int duration = 3000;
+ duration = 500; // 500ms by default
+ if (data) {
+ int input_duration = *((int*)data);
+ if (input_duration > duration) {
+ duration = (input_duration > 5000) ? 5000 : 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 HINT_HANDLED;
+ }
+ s_previous_boost_timespec = cur_boost_timespec;
+ s_previous_duration = duration;
- interaction(duration, ARRAY_SIZE(resources), resources);
+ interaction(duration, ARRAY_SIZE(resources_interaction_boost),
+ resources_interaction_boost);
return HINT_HANDLED;
}
+ default:
+ break;
}
return HINT_NONE;
}