From bea28971359192d1e62459301e357cffe094cbab Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Mon, 19 Oct 2015 14:43:39 -0700 Subject: [PATCH 01/23] power: Add support for tap-to-wake feature control Change-Id: I545902b29f4828c127bc32def6e30b67ce4a3aa7 --- power/Android.mk | 4 ++++ power/power.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/power/Android.mk b/power/Android.mk index 5c727ad..6b8a2c9 100644 --- a/power/Android.mk +++ b/power/Android.mk @@ -58,6 +58,10 @@ LOCAL_CFLAGS += -DSET_INTERACTIVE_EXT LOCAL_SRC_FILES += ../../../../$(TARGET_POWERHAL_SET_INTERACTIVE_EXT) endif +ifneq ($(TARGET_TAP_TO_WAKE_NODE),) +LOCAL_CFLAGS += -DTAP_TO_WAKE_NODE=\"$(TARGET_TAP_TO_WAKE_NODE)\" +endif + ifneq ($(CM_POWERHAL_EXTENSION),) LOCAL_MODULE := power.$(CM_POWERHAL_EXTENSION) else diff --git a/power/power.c b/power/power.c index c489dc2..ac6bbcb 100644 --- a/power/power.c +++ b/power/power.c @@ -459,10 +459,20 @@ void set_interactive(struct power_module *module, int on) pthread_mutex_unlock(&hint_mutex); } +void set_feature(struct power_module *module, feature_t feature, int state) +{ + char tmp_str[NODE_MAX]; +#ifdef TAP_TO_WAKE_NODE + if (feature == POWER_FEATURE_DOUBLE_TAP_TO_WAKE) { + snprintf(tmp_str, NODE_MAX, "%d", state); + sysfs_write(TAP_TO_WAKE_NODE, tmp_str); + } +#endif +} struct power_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, - .module_api_version = POWER_MODULE_API_VERSION_0_2, + .module_api_version = POWER_MODULE_API_VERSION_0_3, .hal_api_version = HARDWARE_HAL_API_VERSION, .id = POWER_HARDWARE_MODULE_ID, .name = "QCOM Power HAL", @@ -473,4 +483,5 @@ struct power_module HAL_MODULE_INFO_SYM = { .init = power_init, .powerHint = power_hint, .setInteractive = set_interactive, + .setFeature = set_feature }; From dfabe509480e168b4b55ea6d1a79b2b85e62b133 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Thu, 29 Oct 2015 23:37:54 -0700 Subject: [PATCH 02/23] power-8974: Explicitly send the magical opcode * We're not handling this automatically anymore in the server because it's highly unreliable. Use the refcounted version of our magic opcode explicitly. Change-Id: Ia092c40db2d880fad93e73d99505752e65d96bd0 --- power/power-8974.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power/power-8974.c b/power/power-8974.c index 9e561c0..a7d3027 100644 --- a/power/power-8974.c +++ b/power/power-8974.c @@ -74,7 +74,7 @@ static void set_power_profile(int profile) { } if (profile == PROFILE_HIGH_PERFORMANCE) { - int resource_values[] = { CPUS_ONLINE_MIN_4, + int resource_values[] = { CPUS_ONLINE_MIN_4, 0x0901, CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX }; perform_hint_action(DEFAULT_PROFILE_HINT_ID, From 15f1c1253804e2aaf98067c78e66b4db56c25a8a Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 21 Oct 2015 14:15:10 -0700 Subject: [PATCH 03/23] power: add support for bias modes on 8994 Change-Id: Id408c468960579c0ad437e588339142d9dc25f5e --- power/power-8994.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/power/power-8994.c b/power/power-8994.c index ed38f1e..6b04ecc 100644 --- a/power/power-8994.c +++ b/power/power-8994.c @@ -52,7 +52,9 @@ static int display_hint_sent; enum { PROFILE_POWER_SAVE, PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE + PROFILE_HIGH_PERFORMANCE, + PROFILE_BIAS_POWER, + PROFILE_BIAS_PERFORMANCE }; static int current_power_profile = PROFILE_BALANCED; @@ -71,7 +73,7 @@ static void set_power_profile(int profile) { } if (profile == PROFILE_POWER_SAVE) { - int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_2, + int resource_values[] = { CPUS_ONLINE_MPD_OVERRIDE, 0x0A03, CPU0_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, CPU2_MAX_FREQ_NONTURBO_MAX - 2, CPU3_MAX_FREQ_NONTURBO_MAX - 2, CPU4_MAX_FREQ_NONTURBO_MAX - 2, CPU5_MAX_FREQ_NONTURBO_MAX - 2, @@ -88,6 +90,22 @@ static void set_power_profile(int profile) { perform_hint_action(DEFAULT_PROFILE_HINT_ID, resource_values, sizeof(resource_values)/sizeof(resource_values[0])); ALOGD("%s: set performance mode", __func__); + } else if (profile == PROFILE_BIAS_POWER) { + int resource_values[] = { 0x0A03, + CPU0_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, + CPU1_MAX_FREQ_NONTURBO_MAX - 2, CPU2_MAX_FREQ_NONTURBO_MAX - 2, + CPU4_MAX_FREQ_NONTURBO_MAX, CPU5_MAX_FREQ_NONTURBO_MAX, + CPU6_MAX_FREQ_NONTURBO_MAX, CPU7_MAX_FREQ_NONTURBO_MAX }; + perform_hint_action(DEFAULT_PROFILE_HINT_ID, + resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + ALOGD("%s: set bias power mode", __func__); + } else if (profile == PROFILE_BIAS_PERFORMANCE) { + int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_MAX, + CPU4_MIN_FREQ_NONTURBO_MAX + 1, CPU5_MIN_FREQ_NONTURBO_MAX + 1, + CPU6_MIN_FREQ_NONTURBO_MAX + 1, CPU7_MIN_FREQ_NONTURBO_MAX + 1 }; + perform_hint_action(DEFAULT_PROFILE_HINT_ID, + resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + ALOGD("%s: set bias perf mode", __func__); } current_power_profile = profile; @@ -172,7 +190,8 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } // Skip other hints in custom power modes - if (current_power_profile != PROFILE_BALANCED) { + if (current_power_profile == PROFILE_POWER_SAVE || + current_power_profile == PROFILE_HIGH_PERFORMANCE) { return HINT_HANDLED; } From bc9b1e2b4b0e984d86792dd10c2148bd750eda79 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Sun, 1 Nov 2015 04:31:46 -0800 Subject: [PATCH 04/23] power-8974: Implement bias modes for 8974 Change-Id: I33316277709d1880b66495ad859ccfa1035c37e5 --- power/power-8974.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/power/power-8974.c b/power/power-8974.c index a7d3027..024d1c6 100644 --- a/power/power-8974.c +++ b/power/power-8974.c @@ -56,7 +56,9 @@ extern int display_boost; enum { PROFILE_POWER_SAVE = 0, PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE + PROFILE_HIGH_PERFORMANCE, + PROFILE_BIAS_POWER, + PROFILE_BIAS_PERFORMANCE }; static int current_power_profile = PROFILE_BALANCED; @@ -80,9 +82,22 @@ static void set_power_profile(int profile) { perform_hint_action(DEFAULT_PROFILE_HINT_ID, resource_values, sizeof(resource_values)/sizeof(resource_values[0])); ALOGD("%s: set performance mode", __func__); - + } else if (profile == PROFILE_BIAS_PERFORMANCE) { + int resource_values[] = { + CPU0_MIN_FREQ_NONTURBO_MAX + 1, CPU1_MIN_FREQ_NONTURBO_MAX + 1, + CPU2_MIN_FREQ_NONTURBO_MAX + 1, CPU2_MIN_FREQ_NONTURBO_MAX + 1 }; + perform_hint_action(DEFAULT_PROFILE_HINT_ID, + resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + ALOGD("%s: set bias perf mode", __func__); + } else if (profile == PROFILE_BIAS_POWER) { + int resource_values[] = { 0x0A03, + CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, + CPU1_MAX_FREQ_NONTURBO_MAX, CPU2_MAX_FREQ_NONTURBO_MAX }; + perform_hint_action(DEFAULT_PROFILE_HINT_ID, + resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + ALOGD("%s: set bias power mode", __func__); } else if (profile == PROFILE_POWER_SAVE) { - int resource_values[] = { CPUS_ONLINE_MAX_LIMIT_2, + int resource_values[] = { 0x0A03, CPUS_ONLINE_MAX_LIMIT_2, CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, CPU2_MAX_FREQ_NONTURBO_MAX, CPU3_MAX_FREQ_NONTURBO_MAX }; perform_hint_action(DEFAULT_PROFILE_HINT_ID, @@ -111,8 +126,9 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } } - // Skip other hints in custom power modes - if (current_power_profile != PROFILE_BALANCED) { + // Skip other hints in high/low power modes + if (current_power_profile == PROFILE_POWER_SAVE || + current_power_profile == PROFILE_HIGH_PERFORMANCE) { return HINT_HANDLED; } From 9dddfdd108c25be2453b0cfa51314b7066696931 Mon Sep 17 00:00:00 2001 From: Scott Mertz Date: Mon, 2 Nov 2015 16:13:41 -0800 Subject: [PATCH 05/23] power: safely convert int to void * Change-Id: I450283103614b8a30fcdfb075d5466fde813f710 --- power/power-8084.c | 4 ++-- power/power-8226.c | 4 ++-- power/power-8610.c | 4 ++-- power/power-8916.c | 4 ++-- power/power-8974.c | 4 ++-- power/power-8994.c | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/power/power-8084.c b/power/power-8084.c index e39bc08..ba930c1 100644 --- a/power/power-8084.c +++ b/power/power-8084.c @@ -98,7 +98,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((int)data); + set_power_profile((intptr_t)data); return HINT_HANDLED; } @@ -116,7 +116,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (int)data / 1000; + int duration = (intptr_t)data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20B, 0x30B, 0x1C00}; if (duration > 0) diff --git a/power/power-8226.c b/power/power-8226.c index 6c69881..ab82f02 100644 --- a/power/power-8226.c +++ b/power/power-8226.c @@ -95,7 +95,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((int)data); + set_power_profile((intptr_t)data); return HINT_HANDLED; } @@ -113,7 +113,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (int)data / 1000; + int duration = (intptr_t)data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F}; if (duration > 0) diff --git a/power/power-8610.c b/power/power-8610.c index 4afc1d9..3f435cb 100644 --- a/power/power-8610.c +++ b/power/power-8610.c @@ -93,7 +93,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((int)data); + set_power_profile((intptr_t)data); return HINT_HANDLED; } @@ -111,7 +111,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (int)data / 1000; + int duration = (intptr_t)data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F}; if (duration > 0) diff --git a/power/power-8916.c b/power/power-8916.c index 7b1ad71..b3ceced 100644 --- a/power/power-8916.c +++ b/power/power-8916.c @@ -381,7 +381,7 @@ int set_interactive_override(struct power_module *module __unused, int on) int power_hint_override(struct power_module *module __unused, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((hintdata)data); + set_power_profile((intptr_t)data); } if (hint == POWER_HINT_LOW_POWER) { @@ -407,7 +407,7 @@ int power_hint_override(struct power_module *module __unused, power_hint_t hint, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (hintdata)data / 1000; + int duration = (intptr_t)data / 1000; int resources[] = { SCHED_BOOST_ON, 0x20D, 0x3E01, 0x101 }; if (duration > 0) diff --git a/power/power-8974.c b/power/power-8974.c index 024d1c6..51704a2 100644 --- a/power/power-8974.c +++ b/power/power-8974.c @@ -114,7 +114,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((int)data); + set_power_profile((intptr_t)data); return HINT_HANDLED; } @@ -144,7 +144,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (int)data / 1000; + int duration = (intptr_t)data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F }; if (duration) diff --git a/power/power-8994.c b/power/power-8994.c index 6b04ecc..4aa2e84 100644 --- a/power/power-8994.c +++ b/power/power-8994.c @@ -174,7 +174,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE && !low_power_mode) { - set_power_profile((hintdata)data); + set_power_profile((intptr_t)data); return HINT_HANDLED; } @@ -213,7 +213,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (hintdata)data / 1000; + int duration = (intptr_t)data / 1000; int resources[] = { SCHED_BOOST_ON }; if (duration > 0) From bdf16fe56cd7ec6cea31aff957e510bffdd13913 Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Tue, 3 Nov 2015 03:27:42 -0800 Subject: [PATCH 06/23] power: Update for PerformanceManager changes * Undo damage caused by the previous patch which broke all hint arguments. We were actually using these wrong to begin with anyway. * Add support for get_profile * Clean up code Change-Id: Ibc3f21bfb7aa46ec97b9b63d09737d4331a5a714 --- power/power-8084.c | 12 +++++------- power/power-8226.c | 12 +++++------- power/power-8610.c | 12 +++++------- power/power-8916.c | 12 +++++------- power/power-8974.c | 19 ++++++++----------- power/power-8994.c | 14 +++++--------- power/power-common.h | 8 ++++++++ power/power.c | 21 ++++++++++++++++++--- 8 files changed, 59 insertions(+), 51 deletions(-) diff --git a/power/power-8084.c b/power/power-8084.c index ba930c1..1958811 100644 --- a/power/power-8084.c +++ b/power/power-8084.c @@ -52,11 +52,9 @@ static int display_hint2_sent; static int first_display_off_hint; extern int display_boost; -enum { - PROFILE_POWER_SAVE = 0, - PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE -}; +int get_number_of_profiles() { + return 3; +} static int current_power_profile = PROFILE_BALANCED; @@ -98,7 +96,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((intptr_t)data); + set_power_profile((*(int32_t *))data); return HINT_HANDLED; } @@ -116,7 +114,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (intptr_t)data / 1000; + int duration = (*(int32_t *))data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20B, 0x30B, 0x1C00}; if (duration > 0) diff --git a/power/power-8226.c b/power/power-8226.c index ab82f02..970392c 100644 --- a/power/power-8226.c +++ b/power/power-8226.c @@ -50,11 +50,9 @@ static int display_hint_sent; -enum { - PROFILE_POWER_SAVE = 0, - PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE -}; +int get_number_of_profiles() { + return 3; +} static int current_power_profile = PROFILE_BALANCED; @@ -95,7 +93,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((intptr_t)data); + set_power_profile(*(int32_t *)data); return HINT_HANDLED; } @@ -113,7 +111,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (intptr_t)data / 1000; + int duration = *(int32_t *)data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F}; if (duration > 0) diff --git a/power/power-8610.c b/power/power-8610.c index 3f435cb..ed7c322 100644 --- a/power/power-8610.c +++ b/power/power-8610.c @@ -50,11 +50,9 @@ static int display_hint_sent; -enum { - PROFILE_POWER_SAVE = 0, - PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE -}; +int get_number_of_profiles() { + return 3; +} static int current_power_profile = PROFILE_BALANCED; @@ -93,7 +91,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((intptr_t)data); + set_power_profile(*(int32_t *)data); return HINT_HANDLED; } @@ -111,7 +109,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (intptr_t)data / 1000; + int duration = *(int32_t *)data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F}; if (duration > 0) diff --git a/power/power-8916.c b/power/power-8916.c index b3ceced..6add9d0 100644 --- a/power/power-8916.c +++ b/power/power-8916.c @@ -65,11 +65,9 @@ int display_boost; static int saved_interactive_mode = -1; static int slack_node_rw_failed = 0; -enum { - PROFILE_POWER_SAVE = 0, - PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE -}; +int get_number_of_profiles() { + return 3; +} static int current_power_profile = PROFILE_BALANCED; @@ -381,7 +379,7 @@ int set_interactive_override(struct power_module *module __unused, int on) int power_hint_override(struct power_module *module __unused, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((intptr_t)data); + set_power_profile(*(int32_t *)data); } if (hint == POWER_HINT_LOW_POWER) { @@ -407,7 +405,7 @@ int power_hint_override(struct power_module *module __unused, power_hint_t hint, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (intptr_t)data / 1000; + int duration = *(int32_t *)data / 1000; int resources[] = { SCHED_BOOST_ON, 0x20D, 0x3E01, 0x101 }; if (duration > 0) diff --git a/power/power-8974.c b/power/power-8974.c index 51704a2..5e726bd 100644 --- a/power/power-8974.c +++ b/power/power-8974.c @@ -53,16 +53,12 @@ static int display_hint2_sent; static int first_display_off_hint; extern int display_boost; -enum { - PROFILE_POWER_SAVE = 0, - PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE, - PROFILE_BIAS_POWER, - PROFILE_BIAS_PERFORMANCE -}; - static int current_power_profile = PROFILE_BALANCED; +int get_number_of_profiles() { + return 5; +} + static void set_power_profile(int profile) { if (profile == current_power_profile) @@ -114,7 +110,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((intptr_t)data); + set_power_profile(*(int32_t *)data); return HINT_HANDLED; } @@ -144,8 +140,9 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (intptr_t)data / 1000; - int resources[] = { CPUS_ONLINE_MIN_2, 0x20F, 0x30F }; + int duration = *(int32_t *)data / 1000; + int resources[] = { CPUS_ONLINE_MIN_2, + 0x20F, 0x30F, 0x40F, 0x50F }; if (duration) interaction(duration, sizeof(resources)/sizeof(resources[0]), resources); diff --git a/power/power-8994.c b/power/power-8994.c index 4aa2e84..0e33c43 100644 --- a/power/power-8994.c +++ b/power/power-8994.c @@ -49,13 +49,9 @@ static int display_hint_sent; -enum { - PROFILE_POWER_SAVE, - PROFILE_BALANCED, - PROFILE_HIGH_PERFORMANCE, - PROFILE_BIAS_POWER, - PROFILE_BIAS_PERFORMANCE -}; +int get_number_of_profiles() { + return 5; +} static int current_power_profile = PROFILE_BALANCED; static int low_power_mode = 0; @@ -174,7 +170,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE && !low_power_mode) { - set_power_profile((intptr_t)data); + set_power_profile(*(int32_t *)data); return HINT_HANDLED; } @@ -213,7 +209,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (intptr_t)data / 1000; + int duration = *(int32_t *)data / 1000; int resources[] = { SCHED_BOOST_ON }; if (duration > 0) diff --git a/power/power-common.h b/power/power-common.h index 49c1f4b..967d7b0 100644 --- a/power/power-common.h +++ b/power/power-common.h @@ -48,3 +48,11 @@ enum CPU_GOV_CHECK { CPU2 = 2, CPU3 = 3 }; + +enum { + PROFILE_POWER_SAVE = 0, + PROFILE_BALANCED, + PROFILE_HIGH_PERFORMANCE, + PROFILE_BIAS_POWER, + PROFILE_BIAS_PERFORMANCE +}; diff --git a/power/power.c b/power/power.c index ac6bbcb..4df823b 100644 --- a/power/power.c +++ b/power/power.c @@ -242,6 +242,11 @@ int __attribute__ ((weak)) set_interactive_override( return HINT_NONE; } +int __attribute__ ((weak)) get_number_of_profiles() +{ + return 0; +} + #ifdef SET_INTERACTIVE_EXT extern void cm_power_set_interactive_ext(int on); #endif @@ -251,7 +256,7 @@ void set_interactive(struct power_module *module, int on) char governor[80]; char tmp_str[NODE_MAX]; struct video_encode_metadata_t video_encode_metadata; - int rc; + int rc = 0; pthread_mutex_lock(&hint_mutex); @@ -459,7 +464,7 @@ void set_interactive(struct power_module *module, int on) pthread_mutex_unlock(&hint_mutex); } -void set_feature(struct power_module *module, feature_t feature, int state) +void set_feature(struct power_module *module __unused, feature_t feature, int state) { char tmp_str[NODE_MAX]; #ifdef TAP_TO_WAKE_NODE @@ -469,6 +474,15 @@ void set_feature(struct power_module *module, feature_t feature, int state) } #endif } + +int get_feature(struct power_module *module __unused, feature_t feature) +{ + if (feature == POWER_FEATURE_SUPPORTED_PROFILES) { + return get_number_of_profiles(); + } + return -1; +} + struct power_module HAL_MODULE_INFO_SYM = { .common = { .tag = HARDWARE_MODULE_TAG, @@ -483,5 +497,6 @@ struct power_module HAL_MODULE_INFO_SYM = { .init = power_init, .powerHint = power_hint, .setInteractive = set_interactive, - .setFeature = set_feature + .setFeature = set_feature, + .getFeature = get_feature }; From eb97f5f580ea50ec9d801e77a74bc135def563ec Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Tue, 3 Nov 2015 18:59:58 -0800 Subject: [PATCH 07/23] power: Fix 8084 compilation issue Change-Id: I395161b71764acb2e0f860066770ada9a307eb3d --- power/power-8084.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/power/power-8084.c b/power/power-8084.c index 1958811..2d33043 100644 --- a/power/power-8084.c +++ b/power/power-8084.c @@ -96,7 +96,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { if (hint == POWER_HINT_SET_PROFILE) { - set_power_profile((*(int32_t *))data); + set_power_profile(*(int32_t *)data); return HINT_HANDLED; } @@ -114,7 +114,7 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, } if (hint == POWER_HINT_CPU_BOOST) { - int duration = (*(int32_t *))data / 1000; + int duration = *(int32_t *)data / 1000; int resources[] = { CPUS_ONLINE_MIN_2, 0x20B, 0x30B, 0x1C00}; if (duration > 0) From bc82e99aeaf311b67c13709506f235d5c0e10835 Mon Sep 17 00:00:00 2001 From: Danny Baumann Date: Thu, 27 Aug 2015 16:08:38 +0200 Subject: [PATCH 08/23] dtbtool: Allow forcing v3 output. Change-Id: Icec0e6446a9c88f2466a8f52278bb9705a6342ff --- dtbtool/dtbtool.c | 426 ++++++++++++++++++++++++++++++-------------- dtbtool/dtbtool.txt | 111 ++++++++++-- 2 files changed, 391 insertions(+), 146 deletions(-) diff --git a/dtbtool/dtbtool.c b/dtbtool/dtbtool.c index 0dbee4d..e82492e 100644 --- a/dtbtool/dtbtool.c +++ b/dtbtool/dtbtool.c @@ -41,11 +41,12 @@ #include #define QCDT_MAGIC "QCDT" /* Master DTB magic */ -#define QCDT_VERSION 1 /* QCDT version */ -#define QCDT_VERSION_NEW 2 /* QCDT version */ +#define QCDT_VERSION 3 /* QCDT version */ #define QCDT_DT_TAG "qcom,msm-id = <" #define QCDT_BOARD_TAG "qcom,board-id = <" +#define QCDT_PMIC_TAG "qcom,pmic-id = <" + #define PAGE_SIZE_DEF 2048 #define PAGE_SIZE_MAX (1024*1024) @@ -64,6 +65,7 @@ struct chipInfo_t { uint32_t platform; uint32_t subtype; uint32_t revNum; + uint32_t pmic_model[4]; uint32_t dtb_size; char *dtb_file; struct chipInfo_t *prev; @@ -90,14 +92,22 @@ struct chipSt_t { struct chipSt_t *t_next; }; +struct chipPt_t { + uint32_t pmic0; + uint32_t pmic1; + uint32_t pmic2; + uint32_t pmic3; + struct chipPt_t *next; + struct chipPt_t *t_next; +}; + char *input_dir; char *output_file; char *dtc_path; char *dt_tag = QCDT_DT_TAG; int verbose; int page_size = PAGE_SIZE_DEF; -int force_v2; - +int output_version = 0; void print_help() { @@ -109,7 +119,8 @@ void print_help() log_info(" --page-size/-s page size in bytes\n"); log_info(" --dt-tag/-d alternate QCDT_DT_TAG\n"); log_info(" --verbose/-v verbose\n"); - log_info(" --force-v2/-2 use dtb v2 format\n"); + log_info(" --force-v2/-2 output dtb v2 format\n"); + log_info(" --force-v3/-3 output dtb v3 format\n"); log_info(" --help/-h this help screen\n"); } @@ -122,13 +133,14 @@ int parse_commandline(int argc, char *const argv[]) {"dtc-path", 1, 0, 'p'}, {"page-size", 1, 0, 's'}, {"dt-tag", 1, 0, 'd'}, + {"force-v2", 0, 0, '2'}, + {"force-v3", 0, 0, '3'}, {"verbose", 0, 0, 'v'}, {"help", 0, 0, 'h'}, - {"force-v2", 0, 0, '2'}, {0, 0, 0, 0} }; - while ((c = getopt_long(argc, argv, "-o:p:s:d:vh2", long_options, NULL)) + while ((c = getopt_long(argc, argv, "-o:p:s:d:23vh", long_options, NULL)) != -1) { switch (c) { case 1: @@ -151,12 +163,17 @@ int parse_commandline(int argc, char *const argv[]) case 'd': dt_tag = optarg; break; + case '2': + case '3': + if (output_version != 0) { + log_err("A version output argument may only be passed once\n"); + return RC_ERROR; + } + output_version = c - '0'; + break; case 'v': verbose = 1; break; - case '2': - force_v2 = 1; - break; case 'h': default: return RC_ERROR; @@ -214,7 +231,11 @@ int chip_add(struct chipInfo_t *c) if ((c->chipset == x->chipset) && (c->platform == x->platform) && (c->subtype == x->subtype) && - (c->revNum == x->revNum)) { + (c->revNum == x->revNum) && + (c->pmic_model[0] == x->pmic_model[0]) && + (c->pmic_model[1] == x->pmic_model[1]) && + (c->pmic_model[2] == x->pmic_model[2]) && + (c->pmic_model[3] == x->pmic_model[3])) { return RC_ERROR; /* duplicate */ } if (!x->next) { @@ -260,15 +281,20 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi size_t line_size; FILE *pfile; int llen; - struct chipInfo_t *chip = NULL, *tmp; + struct chipInfo_t *chip = NULL, *tmp, *chip_t; uint32_t data[3] = {0, 0, 0}; uint32_t data_st[2] = {0, 0}; + uint32_t data_pt[4] = {0, 0, 0, 0}; char *tok, *sptr = NULL; int i, entryValid, entryEnded; - int count = 0, count1 = 0, count2 =0; - int entryValidST, entryEndedST, entryValidDT, entryEndedDT; + int count = 0, count1 = 0, count2 = 0, count3 = 0; + int entryValidST, entryEndedST, entryValidDT, entryEndedDT, entryValidPT, entryEndedPT; struct chipId_t *chipId = NULL, *cId = NULL, *tmp_id = NULL; struct chipSt_t *chipSt = NULL, *cSt = NULL, *tmp_st = NULL; + struct chipPt_t *chipPt = NULL, *cPt = NULL, *tmp_pt = NULL; + struct chipId_t *chipId_tmp = NULL; + struct chipSt_t *chipSt_tmp = NULL; + struct chipPt_t *chipPt_tmp = NULL; line_size = 1024; line = (char *)malloc(line_size); @@ -348,6 +374,10 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi tmp->platform = data[1]; tmp->subtype = 0; tmp->revNum = data[2]; + tmp->pmic_model[0] = 0; + tmp->pmic_model[1] = 0; + tmp->pmic_model[2] = 0; + tmp->pmic_model[3] = 0; tmp->dtb_size = 0; tmp->dtb_file = NULL; tmp->master = chip; @@ -360,7 +390,7 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi log_err("... skip, incorrect '%s' format\n", dt_tag); break; } - } else if (msmversion == 2) { + } else if (msmversion == 2 || msmversion == 3) { if ((pos = strstr(line, dt_tag)) != NULL) { pos += strlen(dt_tag); @@ -450,6 +480,53 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi } } } + + if ((pos = strstr(line,QCDT_PMIC_TAG)) != NULL) { + pos += strlen(QCDT_PMIC_TAG); + entryEndedPT = 0; + for (;entryEndedPT < 1;) { + entryValidPT = 1; + for (i = 0; i < 4; i++) { + tok = strtok_r(pos, " \t", &sptr); + pos = NULL; + if (tok != NULL) { + if (*tok == '>') { + entryEndedPT = 1; + entryValidPT = 0; + break; + } + data_pt[i] = strtoul(tok, NULL, 0); + } else { + data_pt[i] = 0; + entryValidPT = 0; + entryEndedPT = 1; + } + } + if (entryValidPT) { + tmp_pt = (struct chipPt_t *) + malloc(sizeof(struct chipPt_t)); + if (!tmp_pt) { + log_err("Out of memory\n"); + break; + } + + if (!chipPt) { + chipPt = tmp_pt; + cPt = tmp_pt; + chipPt->t_next = NULL; + } else { + tmp_pt->t_next = chipPt->t_next; + chipPt->t_next = tmp_pt; + } + + tmp_pt->pmic0 = data_pt[0]; + tmp_pt->pmic1 = data_pt[1]; + tmp_pt->pmic2 = data_pt[2]; + tmp_pt->pmic3 = data_pt[3]; + count3++; + } + } + } } } } @@ -457,8 +534,6 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi if (line) free(line); - if (force_v2 || msmversion == 2) { - if (count1 == 0) { log_err("... skip, incorrect '%s' format\n", dt_tag); return NULL; @@ -467,53 +542,116 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi log_err("... skip, incorrect '%s' format\n", QCDT_BOARD_TAG); return NULL; } + if (count3 == 0 && msmversion == 3) { + log_err("... skip, incorrect '%s' format\n", QCDT_PMIC_TAG); + return NULL; + } tmp_st = cSt; + tmp_pt = cPt; while (cId != NULL) { while (cSt != NULL) { - tmp = (struct chipInfo_t *) - malloc(sizeof(struct chipInfo_t)); - if (!tmp) { - log_err("Out of memory\n"); - break; - } - if (!chip) { - chip = tmp; - chip->t_next = NULL; + if (msmversion == 3) { + while (cPt != NULL) { + tmp = (struct chipInfo_t *) + malloc(sizeof(struct chipInfo_t)); + if (!tmp) { + log_err("Out of memory\n"); + break; + } + if (!chip) { + chip = tmp; + chip->t_next = NULL; + } else { + tmp->t_next = chip->t_next; + chip->t_next = tmp; + } + + tmp->chipset = cId->chipset; + tmp->platform = cSt->platform; + tmp->revNum = cId->revNum; + tmp->subtype = cSt->subtype; + tmp->pmic_model[0] = cPt->pmic0; + tmp->pmic_model[1] = cPt->pmic1; + tmp->pmic_model[2] = cPt->pmic2; + tmp->pmic_model[3] = cPt->pmic3; + tmp->dtb_size = 0; + tmp->dtb_file = NULL; + tmp->master = chip; + tmp->wroteDtb = 0; + tmp->master_offset = 0; + cPt = cPt->t_next; + } + cPt = tmp_pt; } else { - tmp->t_next = chip->t_next; - chip->t_next = tmp; + tmp = (struct chipInfo_t *) + malloc(sizeof(struct chipInfo_t)); + if (!tmp) { + log_err("Out of memory\n"); + break; + } + if (!chip) { + chip = tmp; + chip->t_next = NULL; + } else { + tmp->t_next = chip->t_next; + chip->t_next = tmp; + } + tmp->chipset = cId->chipset; + tmp->platform = cSt->platform; + tmp->revNum = cId->revNum; + tmp->subtype = cSt->subtype; + tmp->pmic_model[0] = 0; + tmp->pmic_model[1] = 0; + tmp->pmic_model[2] = 0; + tmp->pmic_model[3] = 0; + tmp->dtb_size = 0; + tmp->dtb_file = NULL; + tmp->master = chip; + tmp->wroteDtb = 0; + tmp->master_offset = 0; } - - tmp->chipset = cId->chipset; - tmp->platform = cSt->platform; - tmp->revNum = cId->revNum; - tmp->subtype = cSt->subtype; - tmp->dtb_size = 0; - tmp->dtb_file = NULL; - tmp->master = chip; - tmp->wroteDtb = 0; - tmp->master_offset = 0; - cSt = cSt->t_next; - } cSt = tmp_st; cId = cId->t_next; } - if (entryEndedST == 1 && entryEndedDT == 1) { - pclose(pfile); + if (msmversion == 2) + entryEndedPT = 1; + + /* clear memory*/ + pclose(pfile); + while (chipId) { + chipId_tmp = chipId; + chipId = chipId->t_next; + free(chipId_tmp); + } + while (chipSt) { + chipSt_tmp= chipSt; + chipSt = chipSt->t_next; + free(chipSt_tmp); + } + + while (chipPt) { + chipPt_tmp= chipPt; + chipPt = chipPt->t_next; + free(chipPt_tmp); + } + + if (entryEndedST == 1 && entryEndedDT == 1 && entryEndedPT == 1) { *num = count1; - free(chipSt); - free(chipId); return chip; } - } else { - pclose(pfile); + /* clear memory*/ + while (chip) { + chip_t = chip; + chip = chip->next; + if (chip_t->dtb_file) + free(chip_t->dtb_file); + free(chip_t); } - return NULL; } @@ -562,13 +700,16 @@ int GetVersionInfo(const char *filename) while ((llen = getline(&line, &line_size, pfile)) != -1) { if ((pos = strstr(line,QCDT_BOARD_TAG)) != NULL) { v = 2; + } + if ((pos = strstr(line,QCDT_PMIC_TAG)) != NULL) { + v = 3; break; } } } - if (v == 1) - log_info(" Old Version:%d\n", v); + free(line); + log_info("Version:%d\n", v); return v; } @@ -599,10 +740,10 @@ int main(int argc, char **argv) int out_fd; int flen; int rc = RC_SUCCESS; - int dtb_count = 0, dtb_offset = 0; + int dtb_count = 0, dtb_offset = 0, entry_size; size_t wrote = 0, expected = 0; struct stat st; - uint32_t version = QCDT_VERSION; + uint32_t version = 0; int num; uint32_t dtb_size; int msmversion = 0; @@ -635,88 +776,95 @@ int main(int argc, char **argv) extract "qcom,msm-id" parameter */ while ((dp = readdir(dir)) != NULL) { + if ((dp->d_type == DT_REG)) { + flen = strlen(dp->d_name); + if ((flen > 4) && + (strncmp(&dp->d_name[flen-4], ".dtb", 4) == 0)) { + log_info("Found file: %s ... \n", dp->d_name); + + flen = strlen(input_dir) + strlen(dp->d_name) + 1; + filename = (char *)malloc(flen); + if (!filename) { + log_err("Out of memory\n"); + rc = RC_ERROR; + break; + } + strncpy(filename, input_dir, flen); + strncat(filename, dp->d_name, flen); - flen = strlen(input_dir) + strlen(dp->d_name) + 1; - filename = (char *)malloc(flen); - if (!filename) { - log_err("Out of memory\n"); - rc = RC_ERROR; - break; - } - strncpy(filename, input_dir, flen); - strncat(filename, dp->d_name, flen); - - if (stat(filename, &st) != 0 || !S_ISREG(st.st_mode)) { - free(filename); - continue; - } - - flen = strlen(dp->d_name); - if ((flen <= 4) || (strncmp(&dp->d_name[flen-4], ".dtb", 4) != 0)) { - free(filename); - continue; - } - - log_info("Found file: %s ... ", dp->d_name); - - /* To identify the version number */ - msmversion = force_v2 ? GetVersionInfo(filename) : 1; + /* To identify the version number */ + msmversion = GetVersionInfo(filename); + if (version < msmversion) { + version = msmversion; + } - num = 1; - chip = getChipInfo(filename, &num, msmversion); + num = 1; + chip = getChipInfo(filename, &num, msmversion); - if (msmversion == 1) { - if (!chip) { - log_err("skip, failed to scan for '%s' tag\n", - dt_tag); - free(filename); - continue; - } - } - if (msmversion == 2) { - if (!chip) { - log_err("skip, failed to scan for '%s' or '%s' tag\n", - dt_tag, QCDT_BOARD_TAG); - free(filename); - continue; - } - } + if (msmversion == 1) { + if (!chip) { + log_err("skip, failed to scan for '%s' tag\n", dt_tag); + free(filename); + continue; + } + } + if (msmversion == 2) { + if (!chip) { + log_err("skip, failed to scan for '%s' or '%s' tag\n", + dt_tag, QCDT_BOARD_TAG); + free(filename); + continue; + } + } + if (msmversion == 3) { + if (!chip) { + log_err("skip, failed to scan for '%s', '%s' or '%s' tag\n", + dt_tag, QCDT_BOARD_TAG, QCDT_PMIC_TAG); + free(filename); + continue; + } + } - if (st.st_size == 0) { - log_err("skip, failed to get DTB size\n"); - free(filename); - continue; - } + if ((stat(filename, &st) != 0) || + (st.st_size == 0)) { + log_err("skip, failed to get DTB size\n"); + free(filename); + continue; + } - log_info("chipset: %u, rev: %u, platform: %u, subtype: %u\n", - chip->chipset, chip->revNum, chip->platform, chip->subtype); + log_info("chipset: %u, rev: %u, platform: %u, subtype: %u, pmic0: %u, pmic1: %u, pmic2: %u, pmic3: %u\n", + chip->chipset, chip->revNum, chip->platform, chip->subtype, + chip->pmic_model[0], chip->pmic_model[1], chip->pmic_model[2], chip->pmic_model[3]); - for (t_chip = chip->t_next; t_chip; t_chip = t_chip->t_next) { - log_info(" additional chipset: %u, rev: %u, platform: %u, subtype: %u\n", - t_chip->chipset, t_chip->revNum, t_chip->platform, t_chip->subtype); - } + for (t_chip = chip->t_next; t_chip; t_chip = t_chip->t_next) { + log_info("additional chipset: %u, rev: %u, platform: %u, subtype: %u, pmic0: %u, pmic1: %u, pmic2: %u, pmic3: %u\n", + t_chip->chipset, t_chip->revNum, t_chip->platform, t_chip->subtype, + t_chip->pmic_model[0], t_chip->pmic_model[1], t_chip->pmic_model[2], t_chip->pmic_model[3]); + } - rc = chip_add(chip); - if (rc != RC_SUCCESS) { - log_err("... duplicate info, skipped\n"); - free(filename); - continue; - } + rc = chip_add(chip); + if (rc != RC_SUCCESS) { + log_err("... duplicate info, skipped\n"); + free(filename); + continue; + } - dtb_count++; + dtb_count++; - chip->dtb_size = st.st_size + - (page_size - (st.st_size % page_size)); - chip->dtb_file = filename; + chip->dtb_size = st.st_size + + (page_size - (st.st_size % page_size)); + chip->dtb_file = filename; - for (t_chip = chip->t_next; t_chip; t_chip = t_chip->t_next) { - rc = chip_add(t_chip); - if (rc != RC_SUCCESS) { - log_err("... duplicate info, skipped (chipset %u, rev: %u, platform: %u, subtype %u:\n", - t_chip->chipset, t_chip->revNum, t_chip->platform, t_chip->subtype); - continue; + for (t_chip = chip->t_next; t_chip; t_chip = t_chip->t_next) { + rc = chip_add(t_chip); + if (rc != RC_SUCCESS) { + log_err("... duplicate info, skipped (chipset %u, rev: %u, platform: %u, subtype: %u\n", + t_chip->chipset, t_chip->revNum, t_chip->platform, t_chip->subtype); + continue; + } + dtb_count++; + } } - dtb_count++; } } closedir(dir); @@ -741,8 +889,16 @@ int main(int argc, char **argv) goto cleanup; } - if (force_v2) { - version = QCDT_VERSION_NEW; + if (output_version != 0) { + version = output_version; + } + + if (output_version == 1) { + entry_size = 20; + } else if (output_version == 2) { + entry_size = 24; + } else { + entry_size = 40; } /* Write header info */ @@ -752,9 +908,10 @@ int main(int argc, char **argv) /* #DTB */ /* Calculate offset of first DTB block */ - dtb_offset = 12 + /* header */ - ((force_v2 ? 24 : 20) * dtb_count) + /* DTB table entries */ - 4; /* end of table indicator */ + dtb_offset = 12 + /* header */ + (entry_size * dtb_count) + /* DTB table entries */ + 4; /* end of table indicator */ + /* Round up to page size */ padding = page_size - (dtb_offset % page_size); dtb_offset += padding; @@ -763,17 +920,28 @@ int main(int argc, char **argv) /* Write index table: chipset platform - subtype + subtype (v2/v3 only) soc rev + pmic model0 (v3 only) + pmic model1 (v3 only) + pmic model2 (v3 only) + pmic model3 (v3 only) dtb offset dtb size */ for (chip = chip_list; chip; chip = chip->next) { wrote += write(out_fd, &chip->chipset, sizeof(uint32_t)); wrote += write(out_fd, &chip->platform, sizeof(uint32_t)); - if (force_v2) + if (output_version >= 2) { wrote += write(out_fd, &chip->subtype, sizeof(uint32_t)); + } wrote += write(out_fd, &chip->revNum, sizeof(uint32_t)); + if (output_version >= 3) { + wrote += write(out_fd, &chip->pmic_model[0], sizeof(uint32_t)); + wrote += write(out_fd, &chip->pmic_model[1], sizeof(uint32_t)); + wrote += write(out_fd, &chip->pmic_model[2], sizeof(uint32_t)); + wrote += write(out_fd, &chip->pmic_model[3], sizeof(uint32_t)); + } if (chip->master->master_offset != 0) { wrote += write(out_fd, &chip->master->master_offset, sizeof(uint32_t)); } else { diff --git a/dtbtool/dtbtool.txt b/dtbtool/dtbtool.txt index e738ef8..1aa0be4 100644 --- a/dtbtool/dtbtool.txt +++ b/dtbtool/dtbtool.txt @@ -1,4 +1,4 @@ -Copyright (c) 2012, The Linux Foundation. All rights reserved. +Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. Redistribution and use in source form and compiled forms (SGML, HTML, PDF, PostScript, RTF and so forth) with or without modification, are @@ -33,6 +33,7 @@ Android - Table of Device Tree 0) Document revision v1.0 - Initial version (dng) + v1.1 - Add v2 format to allow subtype (dng) 1) Android boot image: ---------------------- @@ -72,16 +73,26 @@ Android - Table of Device Tree x +------------------+ | | MAGIC ("QCDT") | 4B | +------------------+ - header | VERSION | uint32 (initial version 1) + header | VERSION | uint32 (version 3) | +------------------+ | | num of DTBs | uint32 (number of DTB entries) x +------------------+ | | platform id #1 | uint32 (e.g. ID for MSM8974) | +------------------+ | | variant id #1 | uint32 (e.g. ID for CDP, MTP) + | +------------------+ + | | subtype id #1 | uint32 (e.g. ID for subtype) (QCDT v2) device +------------------+ #1 | soc rev #1 | uint32 (e.g. MSM8974 v2) entry +------------------+ + | | pmic0 #1 | uint32 (pmic0-> first smallest SID of existing pmic) + | +------------------+ + | | pmic1 #1 | uint32 (pmic1-> secondary smallest SID of existing pmic) + | +------------------+ + | | pmic2 #1 | uint32 (pmic2-> third smallest SID of existing pmic) + | +------------------+ + | | pmic3 #1 | uint32 (pmic3-> fourth smallest SID of existing pmic) + | +------------------+ | | offset #1 | uint32 (byte offset from start/before MAGIC | +------------------+ to DTB entry) | | size #1 | uint32 (size in bytes of DTB blob) @@ -95,8 +106,18 @@ Android - Table of Device Tree | +------------------+ device | variant id #Z | uint32 (e.g. ID for CDP, MTP) #Z +------------------+ - entry | soc rev #Z | uint32 (e.g. MSM8974 v2) + entry | subtype id #Z | uint32 (e.g. ID for subtype) (QCDT v2) (last) +------------------+ + | | soc rev #Z | uint32 (e.g. MSM8974 v2) + | +------------------+ + | | pmic0 #1 | uint32 (pmic0-> first smallest SID of existing pmic) + | +------------------+ + | | pmic1 #1 | uint32 (pmic1-> secondary smallest SID of existing pmic) + | +------------------+ + | | pmic2 #1 | uint32 (pmic2-> third smallest SID of existing pmic) + | +------------------+ + | | pmic3 #1 | uint32 (pmic3-> fourth smallest SID of existing pmic) + | +------------------+ | | offset #Z | uint32 (byte offset from start/before MAGIC x +------------------+ to DTB entry) | 0 ("zero") | uint32 (end of list delimiter) @@ -122,25 +143,63 @@ Android - Table of Device Tree 3) Operations ------------- 3.1) Build-time: - 1) Each DTS per device will add a "qcom,msm-id" triplet + 1) Each DTS per device will add a "qcom,msm-id" entry e.g. for msm8974-sim.dts, add - qcom,msm-id = ; - x = ID for msm8974 - y = ID for CDP, MTP, etc. - z = ID for soc revision - The triplet can optionally be an array of triplets: - qcom,msm-id = , , ...; + qcom,msm-id = ; + or + qcom,msm-id = ; + qcom,board-id = ; + or + qcom,msm-id = ; + qcom,board-id = ; + qcom,pmic-id = ; + x = ID for msm8974 + y = ID for CDP, MTP, etc. + y' = ID for subtype (assumed zero if absent) + z = ID for soc revision + a = pmic0 + b = pmic1 + c = pmic2 + d = pmic3 + SBL populates the pmic entries always in ascending order of SID, so + pmic0-> SID0, pmic1-> SID1, pmic2-> SID2, pmic3-> SID3. + e.g. for qcom,pmic-id = + Board X = MSM8994 + PM8994 + PMI8994 (Existing boards [ROW]) + Board Y = MSM8994 + PM8994 + PMI8994 + PM8004 (Internal SS board variant) + Board Z = MSM8994 + PM8994 + PM8004 (Boards that SS will be making) + + For all boards X, Y, and Z, PMICs have the following SIDs and REVID SUBTYPEs + (i.e. PMIC Model): + PM8994 - SID 0 and 1; subtype = 9 + PMI8994 - SID 2 and 3; subtype = 10 + PM8004 - SID 4 and 5; subtype = 12 + + LK using SMEM PMIC info(1 as major and 0 as minor version for example): + Board X: qcom,pmic-id = <0x0109 0x010A 0x0 0x0>; + Board Y: qcom,pmic-id = <0x0109 0x010A 0x010C 0x0>; + Board Z: qcom,pmic-id = <0x0109 0x010C 0x0 0x0>; + + The entry can optionally be an array: + qcom,msm-id = , , ...; + or + qcom,msm-id = , , ...; + qcom,board-id = , ...; + or + qcom,msm-id = , , ...; + qcom,board-id = , ...; + qcom,pmic-id = , ...; + Note that qcom,msm-id, qcom,board-id and qcom,pmic-id are not matched pairs. 2) Kernel compile will generate the DTB 3) Android build will run a new tool (dtbTool) a) scan the DTB output directory for all compiled DTB - b) decompile the DTB for "qcom,msm-id" + b) decompile the DTB for "qcom,msm-id"/"qcom,board-id"/"qcom,pmic-id" c) generate the QC table of device tree in sorted - order (platform, variant, soc rev) + order (platform, variant, subtype, soc rev, pmic0, pmic1, pmic2, pmic3) d) modified mkbootimg will merge new table of DT 3.2) Run-time: - 1) LK bootloader will obtain MSM id/variant/soc rev info - either from early bootloaders or via other means + 1) LK bootloader will obtain platform id/variant/subtype/soc rev/major ver/minor ver + /pmic0/pmic1/pmic2/pmic3 info either from early bootloaders or via other means 2) LK bootloader will check entries #10 for non-zero value (set to zero for standard boot.img). If the value is non-zero, refer to page section after @@ -150,9 +209,27 @@ Android - Table of Device Tree QCDT version) 5) LK scans through the QCDT table to look for matching entry. Search order is: - 1) platform ID exact match - 2) variant ID exact match - 3) select the highest soc rev in QCDT that is + 1) msm ID exact match + 2) Platform type exact match + 3) subtype ID exact match + 4) HLOS subtype exact match + 5) Pmic0 model ID exact match + 6) Pmic1 model ID exact match + 7) Pmic2 model ID exact match + 8) Pmic3 model ID exact match + 9) foundry ID, look for exact match, if not found choose + device tree with foundry-id(0x0) + 10) select the highest soc rev in QCDT that is equal to or lower than the runtime detected soc rev + 11) select the highest major&minor ver in QCDT that is + equal to or lower than the runtime detected major ver + 12) select the highest pmic0 major&minor in QCDT that is + equal to or lower than the runtime detected pmic0 + 13) select the highest pmic1 major&minor in QCDT that is + equal to or lower than the runtime detected pmic1 + 14) select the highest pmic2 major&minor in QCDT that is + equal to or lower than the runtime detected pmic2 + 15) select the highest pmic3 major&minor in QCDT that is + equal to or lower than the runtime detected pmic3 6) Load the matching DTB blob to the tags addr 7) LK pass the correct DTB to the kernel From 3d4e4c880b1afb2978d59b2ad1d0e95e1b006a62 Mon Sep 17 00:00:00 2001 From: Dan Pasanen Date: Sun, 8 Nov 2015 10:16:14 -0600 Subject: [PATCH 09/23] dtbtool: use detected version to determine entry_size * rename output_version to version_override so its more obvious what it does Change-Id: I139e23ef99335247b5ec24078be2a74de38ab28d --- dtbtool/dtbtool.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dtbtool/dtbtool.c b/dtbtool/dtbtool.c index e82492e..20bc014 100644 --- a/dtbtool/dtbtool.c +++ b/dtbtool/dtbtool.c @@ -107,7 +107,7 @@ char *dtc_path; char *dt_tag = QCDT_DT_TAG; int verbose; int page_size = PAGE_SIZE_DEF; -int output_version = 0; +int version_override = 0; void print_help() { @@ -165,11 +165,11 @@ int parse_commandline(int argc, char *const argv[]) break; case '2': case '3': - if (output_version != 0) { + if (version_override != 0) { log_err("A version output argument may only be passed once\n"); return RC_ERROR; } - output_version = c - '0'; + version_override = c - '0'; break; case 'v': verbose = 1; @@ -889,13 +889,13 @@ int main(int argc, char **argv) goto cleanup; } - if (output_version != 0) { - version = output_version; + if (version_override != 0) { + version = version_override; } - if (output_version == 1) { + if (version == 1) { entry_size = 20; - } else if (output_version == 2) { + } else if (version == 2) { entry_size = 24; } else { entry_size = 40; @@ -932,11 +932,11 @@ int main(int argc, char **argv) for (chip = chip_list; chip; chip = chip->next) { wrote += write(out_fd, &chip->chipset, sizeof(uint32_t)); wrote += write(out_fd, &chip->platform, sizeof(uint32_t)); - if (output_version >= 2) { + if (version >= 2) { wrote += write(out_fd, &chip->subtype, sizeof(uint32_t)); } wrote += write(out_fd, &chip->revNum, sizeof(uint32_t)); - if (output_version >= 3) { + if (version >= 3) { wrote += write(out_fd, &chip->pmic_model[0], sizeof(uint32_t)); wrote += write(out_fd, &chip->pmic_model[1], sizeof(uint32_t)); wrote += write(out_fd, &chip->pmic_model[2], sizeof(uint32_t)); From 0dee43f13662978b86ca5f92b791698af96dd515 Mon Sep 17 00:00:00 2001 From: Dan Pasanen Date: Sun, 8 Nov 2015 09:56:04 -0600 Subject: [PATCH 10/23] dtbtool: use stat to determine file type if its unknown * Some filesystems (xfs) return 0 for d_type on readdir * If the file type is unknown, attempt a stat call to see if it can be found that way. Change-Id: I2f7a90a73cd9614aa34cd4654d007393f45db9f9 --- dtbtool/dtbtool.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dtbtool/dtbtool.c b/dtbtool/dtbtool.c index 20bc014..8867a2b 100644 --- a/dtbtool/dtbtool.c +++ b/dtbtool/dtbtool.c @@ -776,7 +776,19 @@ int main(int argc, char **argv) extract "qcom,msm-id" parameter */ while ((dp = readdir(dir)) != NULL) { - if ((dp->d_type == DT_REG)) { + if (dp->d_type == DT_UNKNOWN) { + struct stat statbuf; + char name[PATH_MAX]; + snprintf(name, sizeof(name), "%s%s%s", + input_dir, + (input_dir[strlen(input_dir) - 1] == '/' ? "" : "/"), + dp->d_name); + if (!stat(name, &statbuf) && S_ISREG(statbuf.st_mode)) { + dp->d_type = DT_REG; + } + } + + if (dp->d_type == DT_REG) { flen = strlen(dp->d_name); if ((flen > 4) && (strncmp(&dp->d_name[flen-4], ".dtb", 4) == 0)) { From f0a656230b862e51d0c8a9db997c0de52a1639e5 Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Mon, 9 Nov 2015 10:12:06 -0800 Subject: [PATCH 11/23] Fix error checking of open file error comparison of constant 0 with boolean expression is always false Change-Id: Ie166d70cc6f509a471e62272b29b1bfe9d9487ea --- dtbtool/dtbtool.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dtbtool/dtbtool.c b/dtbtool/dtbtool.c index 8867a2b..9df62a9 100644 --- a/dtbtool/dtbtool.c +++ b/dtbtool/dtbtool.c @@ -895,7 +895,7 @@ int main(int argc, char **argv) log_info("\nGenerating master DTB... "); out_fd = open(output_file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); - if (!out_fd < 0) { + if (out_fd == -1) { log_err("Cannot create '%s'\n", output_file); rc = RC_ERROR; goto cleanup; From cbabda208601979821ed4674221deb626e0f5b38 Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Mon, 9 Nov 2015 10:10:09 -0800 Subject: [PATCH 12/23] Fix build breaks on M Fix "Undeclared identifier 'PATH_MAX'" on darwin. Change-Id: Icb2085f66df3601918dca9b30f8de801e0b16acd --- dtbtool/dtbtool.c | 1 + 1 file changed, 1 insertion(+) diff --git a/dtbtool/dtbtool.c b/dtbtool/dtbtool.c index 9df62a9..94b85dc 100644 --- a/dtbtool/dtbtool.c +++ b/dtbtool/dtbtool.c @@ -39,6 +39,7 @@ #include #include #include +#include #define QCDT_MAGIC "QCDT" /* Master DTB magic */ #define QCDT_VERSION 3 /* QCDT version */ From a29c3490779af68c124fc4167f99ead483e43f40 Mon Sep 17 00:00:00 2001 From: Scott Mertz Date: Thu, 29 Oct 2015 11:26:12 -0700 Subject: [PATCH 13/23] power: enable perf options for power bias Change-Id: Ibc750868cace9f8eef06c90eb5f46fc6013f97d8 --- power/power-8994.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/power/power-8994.c b/power/power-8994.c index 0e33c43..90a4f45 100644 --- a/power/power-8994.c +++ b/power/power-8994.c @@ -87,7 +87,7 @@ static void set_power_profile(int profile) { resource_values, sizeof(resource_values)/sizeof(resource_values[0])); ALOGD("%s: set performance mode", __func__); } else if (profile == PROFILE_BIAS_POWER) { - int resource_values[] = { 0x0A03, + int resource_values[] = { 0x0A03, 0x0902, CPU0_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, CPU1_MAX_FREQ_NONTURBO_MAX - 2, CPU2_MAX_FREQ_NONTURBO_MAX - 2, CPU4_MAX_FREQ_NONTURBO_MAX, CPU5_MAX_FREQ_NONTURBO_MAX, From 13478752a13af42388adad312a888d9c59358481 Mon Sep 17 00:00:00 2001 From: Keith Mok Date: Fri, 13 Nov 2015 09:46:14 -0800 Subject: [PATCH 14/23] Refactor TARGET_TAP_TO_WAKE_NODE Add TARGET_POWER_SET_FEATURE_LIB, since other devices are not simply writing a 0/1 to a device node. TARGET_TAP_TO_WAKE_NODE still valid and both TARGET_TAP_TO_WAKE_NODE and TARGET_POWER_SET_FEATURE_LIB are allowed to be coexist. (Currently set_feature only got double tap wake, but may be extended in future) Change-Id: I5c6204fd38a6fbe48e8aac49843bfa047c4b6436 --- power/Android.mk | 8 +++++++- power/power-feature-default.c | 24 ++++++++++++++++++++++++ power/power-feature.h | 24 ++++++++++++++++++++++++ power/power.c | 7 +++++-- 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 power/power-feature-default.c create mode 100644 power/power-feature.h diff --git a/power/Android.mk b/power/Android.mk index 6b8a2c9..718004e 100644 --- a/power/Android.mk +++ b/power/Android.mk @@ -59,7 +59,13 @@ LOCAL_SRC_FILES += ../../../../$(TARGET_POWERHAL_SET_INTERACTIVE_EXT) endif ifneq ($(TARGET_TAP_TO_WAKE_NODE),) -LOCAL_CFLAGS += -DTAP_TO_WAKE_NODE=\"$(TARGET_TAP_TO_WAKE_NODE)\" + LOCAL_CFLAGS += -DTAP_TO_WAKE_NODE=\"$(TARGET_TAP_TO_WAKE_NODE)\" +endif + +ifeq ($(TARGET_POWER_SET_FEATURE_LIB),) + LOCAL_SRC_FILES += power-feature-default.c +else + LOCAL_STATIC_LIBRARIES += $(TARGET_POWER_SET_FEATURE_LIB) endif ifneq ($(CM_POWERHAL_EXTENSION),) diff --git a/power/power-feature-default.c b/power/power-feature-default.c new file mode 100644 index 0000000..c432aa8 --- /dev/null +++ b/power/power-feature-default.c @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "power-feature.h" + +void set_device_specific_feature(struct power_module *module __unused, + feature_t feature __unused, int state __unused) +{ +} + diff --git a/power/power-feature.h b/power/power-feature.h new file mode 100644 index 0000000..595e3dd --- /dev/null +++ b/power/power-feature.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2015 The CyanogenMod Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _QCOM_POWER_FEATURE_H +#define _QCOM_POWER_FEATURE_H + +#include + +void set_device_specific_feature(struct power_module *module, feature_t feature, int state); + +#endif diff --git a/power/power.c b/power/power.c index 4df823b..518e990 100644 --- a/power/power.c +++ b/power/power.c @@ -49,6 +49,7 @@ #include "hint-data.h" #include "performance.h" #include "power-common.h" +#include "power-feature.h" static int saved_dcvs_cpu0_slack_max = -1; static int saved_dcvs_cpu0_slack_min = -1; @@ -464,15 +465,17 @@ void set_interactive(struct power_module *module, int on) pthread_mutex_unlock(&hint_mutex); } -void set_feature(struct power_module *module __unused, feature_t feature, int state) +void set_feature(struct power_module *module, feature_t feature, int state) { - char tmp_str[NODE_MAX]; #ifdef TAP_TO_WAKE_NODE + char tmp_str[NODE_MAX]; if (feature == POWER_FEATURE_DOUBLE_TAP_TO_WAKE) { snprintf(tmp_str, NODE_MAX, "%d", state); sysfs_write(TAP_TO_WAKE_NODE, tmp_str); + return; } #endif + set_device_specific_feature(module, feature, state); } int get_feature(struct power_module *module __unused, feature_t feature) From ac9c8a8fec3b76b3cabc21527b96e61b98d90d0a Mon Sep 17 00:00:00 2001 From: Scott Mertz Date: Tue, 8 Dec 2015 16:12:55 -0800 Subject: [PATCH 15/23] dtbtool: Recursively search input directory for dtb files On some kernels (msm8916), the build creates an empty subdirectory in the dtb output directory. arch/arm64/boot/dts <-- dtb location arch/arm64/boot/dts/qcom <-- empty directory The dt_image.mk will find the first directory which exists in its predefined list of directories. The empty directory then causes no dtb files to be found. Rather than try to specify the correct directory, make dtbtool smart enough to traverse into subdirectories and find all dtb files. An accompanying change to dt_image.mk is required to only search the most generic path. Change-Id: I56e7344c5c6d1e6a56d939cf8aaf3da9f1e6a714 --- dtbtool/dtbtool.c | 146 +++++++++++++++++++++++++++------------------- 1 file changed, 87 insertions(+), 59 deletions(-) diff --git a/dtbtool/dtbtool.c b/dtbtool/dtbtool.c index 94b85dc..1ef54d8 100644 --- a/dtbtool/dtbtool.c +++ b/dtbtool/dtbtool.c @@ -657,7 +657,7 @@ struct chipInfo_t *getChipInfo(const char *filename, int *num, uint32_t msmversi } /* Get the version-id based on dtb files */ -int GetVersionInfo(const char *filename) +uint32_t GetVersionInfo(const char *filename) { const char str1[] = "dtc -I dtb -O dts \""; const char str2[] = "\" 2>&1"; @@ -666,7 +666,7 @@ int GetVersionInfo(const char *filename) size_t line_size; FILE *pfile; int llen; - int v = 1; + uint32_t v = 1; line_size = 1024; line = (char *)malloc(line_size); @@ -715,63 +715,23 @@ int GetVersionInfo(const char *filename) return v; } -/* Extract 'qcom,msm-id' 'qcom,board-id' parameter from DTB - v1 format: - qcom,msm-id = [, ...]; - v2 format: - qcom,msm-id = [, ...; - qcom,board-id = [, ...; - Fields: - x = chipset - y = platform - y' = subtype - z = soc rev - */ -int main(int argc, char **argv) +static int find_dtb(const char *path, uint32_t *version) { - char buf[COPY_BLK]; - struct chipInfo_t *chip, *t_chip; struct dirent *dp; - FILE *pInputFile; - char *filename; - int padding; - uint8_t *filler = NULL; - int numBytesRead = 0; - int totBytesRead = 0; - int out_fd; int flen; - int rc = RC_SUCCESS; - int dtb_count = 0, dtb_offset = 0, entry_size; - size_t wrote = 0, expected = 0; + char *filename; + struct chipInfo_t *chip, *t_chip; struct stat st; - uint32_t version = 0; int num; - uint32_t dtb_size; - int msmversion = 0; - - log_info("DTB combiner:\n"); - - if (parse_commandline(argc, argv) != RC_SUCCESS) { - print_help(); - return RC_ERROR; - } - - log_info(" Input directory: '%s'\n", input_dir); - log_info(" Output file: '%s'\n", output_file); + int rc = RC_SUCCESS; + uint32_t msmversion = 0; + int dtb_count = 0; - DIR *dir = opendir(input_dir); + DIR *dir = opendir(path); if (!dir) { - log_err("Failed to open input directory '%s'\n", input_dir); - return RC_ERROR; - } - - filler = (uint8_t *)malloc(page_size); - if (!filler) { - log_err("Out of memory\n"); - closedir(dir); + log_err("Failed to open input directory '%s'\n", path); return RC_ERROR; } - memset(filler, 0, page_size); /* Open the .dtb files in the specified path, decompile and extract "qcom,msm-id" parameter @@ -781,34 +741,50 @@ int main(int argc, char **argv) struct stat statbuf; char name[PATH_MAX]; snprintf(name, sizeof(name), "%s%s%s", - input_dir, - (input_dir[strlen(input_dir) - 1] == '/' ? "" : "/"), + path, + (path[strlen(path) - 1] == '/' ? "" : "/"), dp->d_name); - if (!stat(name, &statbuf) && S_ISREG(statbuf.st_mode)) { - dp->d_type = DT_REG; + if (!stat(name, &statbuf)) { + if (S_ISREG(statbuf.st_mode)) { + dp->d_type = DT_REG; + } else if (S_ISDIR(statbuf.st_mode)) { + dp->d_type = DT_DIR; + } } } - if (dp->d_type == DT_REG) { + if (dp->d_type == DT_DIR) { + char name[PATH_MAX]; + if (dp->d_name[0] == '.') { + continue; + } + snprintf(name, sizeof(name), "%s%s%s%s", + path, + (path[strlen(path) - 1] == '/' ? "" : "/"), + dp->d_name, + "/"); + log_info("Searching subdir: %s ... \n", name); + dtb_count += find_dtb(name, version); + } else if (dp->d_type == DT_REG) { flen = strlen(dp->d_name); if ((flen > 4) && (strncmp(&dp->d_name[flen-4], ".dtb", 4) == 0)) { log_info("Found file: %s ... \n", dp->d_name); - flen = strlen(input_dir) + strlen(dp->d_name) + 1; + flen = strlen(path) + strlen(dp->d_name) + 1; filename = (char *)malloc(flen); if (!filename) { log_err("Out of memory\n"); rc = RC_ERROR; break; } - strncpy(filename, input_dir, flen); + strncpy(filename, path, flen); strncat(filename, dp->d_name, flen); /* To identify the version number */ msmversion = GetVersionInfo(filename); - if (version < msmversion) { - version = msmversion; + if (*version < msmversion) { + *version = msmversion; } num = 1; @@ -881,6 +857,58 @@ int main(int argc, char **argv) } } closedir(dir); + return dtb_count; +} + +/* Extract 'qcom,msm-id' 'qcom,board-id' parameter from DTB + v1 format: + qcom,msm-id = [, ...]; + v2 format: + qcom,msm-id = [, ...; + qcom,board-id = [, ...; + Fields: + x = chipset + y = platform + y' = subtype + z = soc rev + */ +int main(int argc, char **argv) +{ + char buf[COPY_BLK]; + struct chipInfo_t *chip; + FILE *pInputFile; + int padding; + uint8_t *filler = NULL; + int numBytesRead = 0; + int totBytesRead = 0; + int out_fd; + int rc = RC_SUCCESS; + int dtb_count = 0, dtb_offset = 0, entry_size; + size_t wrote = 0, expected = 0; + uint32_t dtb_size; + uint32_t version = 0; + char *filename; + + log_info("DTB combiner:\n"); + + if (parse_commandline(argc, argv) != RC_SUCCESS) { + print_help(); + return RC_ERROR; + } + + log_info(" Input directory: '%s'\n", input_dir); + log_info(" Output file: '%s'\n", output_file); + + + filler = (uint8_t *)malloc(page_size); + if (!filler) { + log_err("Out of memory\n"); + return RC_ERROR; + } + memset(filler, 0, page_size); + + dtb_count = find_dtb(input_dir, &version); + log_info("=> Found %d unique DTB(s)\n", dtb_count); if (!dtb_count) From 38807b1953eefb544e417156b1296c356aff897c Mon Sep 17 00:00:00 2001 From: Steve Kondik Date: Wed, 16 Dec 2015 03:54:34 -0500 Subject: [PATCH 16/23] power: Reduce interactive timer with screen off * To reduce power consumption further. * This is the standard QC configuration, but was disabled in CM due to Bluetooth audio issues when toggling the screen off. This no longer seems to be the case on M. Change-Id: Ic2a8c23f8c6e765c42e3a71ffafa93098a0d1585 --- power/power.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/power/power.c b/power/power.c index 518e990..1c2b84f 100644 --- a/power/power.c +++ b/power/power.c @@ -229,6 +229,7 @@ static void power_hint(__attribute__((unused)) struct power_module *module, powe case POWER_HINT_VIDEO_DECODE: process_video_decode_hint(data); break; + default: break; } @@ -289,7 +290,7 @@ void set_interactive(struct power_module *module, int on) } } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - int resource_values[] = {THREAD_MIGRATION_SYNC_OFF}; + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; if (!display_hint_sent) { perform_hint_action(DISPLAY_STATE_HINT_ID, From 4fdf322970d2e7ba7cd6f4feb460e7347ee21b34 Mon Sep 17 00:00:00 2001 From: Zhao Wei Liew Date: Tue, 17 Nov 2015 17:45:03 +0800 Subject: [PATCH 17/23] power-8960: Implement performance profiles Add the 3 standard profiles and hook low power mode to the powersaving performance profile. Change-Id: Id7d16f97c177a790427d848e8ccea3286cf37a4e --- power/power-8960.c | 109 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/power/power-8960.c b/power/power-8960.c index 045eb12..b1103cd 100644 --- a/power/power-8960.c +++ b/power/power-8960.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2015, The CyanogenMod Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -49,6 +50,114 @@ static int display_hint_sent; +static int current_power_profile = PROFILE_BALANCED; + +static int is_8064 = -1; + +int get_number_of_profiles() { + return 3; +} + +static int is_target_8064() /* Returns value=8064 if target is 8064 else value 0 */ +{ + int fd; + char buf[10] = {0}; + + if (is_8064 >= 0) + return is_8064; + + fd = open("/sys/devices/system/soc/soc0/id", O_RDONLY); + if (fd >= 0) { + if (read(fd, buf, sizeof(buf) - 1) == -1) { + ALOGW("Unable to read soc_id"); + is_8064 = 0; + } else { + int soc_id = atoi(buf); + if (soc_id == 153) { + is_8064 = 8064; + } + } + } + close(fd); + return is_8064; +} + +static int profile_high_performance_8960[3] = { + CPUS_ONLINE_MIN_2, + CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX +}; + +static int profile_high_performance_8064[5] = { + CPUS_ONLINE_MIN_4, + CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, + CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX +}; + +static int profile_power_save_8960[2] = { + CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX +}; + +static int profile_power_save_8064[5] = { + CPUS_ONLINE_MAX_LIMIT_2, + CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, + CPU2_MAX_FREQ_NONTURBO_MAX, CPU3_MAX_FREQ_NONTURBO_MAX +}; + +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_HIGH_PERFORMANCE) { + int *resource_values = is_target_8064() ? + profile_high_performance_8064 : profile_high_performance_8960; + + perform_hint_action(DEFAULT_PROFILE_HINT_ID, + resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + ALOGD("%s: set performance mode", __func__); + } else if (profile == PROFILE_POWER_SAVE) { + int* resource_values = is_target_8064() ? + profile_power_save_8064 : profile_power_save_8960; + + perform_hint_action(DEFAULT_PROFILE_HINT_ID, + resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + ALOGD("%s: set powersave", __func__); + } + + current_power_profile = profile; +} + +int power_hint_override(__attribute__((unused)) struct power_module *module, + power_hint_t hint, void *data) +{ + if (hint == POWER_HINT_SET_PROFILE) { + set_power_profile(*(int32_t *)data); + return HINT_HANDLED; + } + + if (hint == POWER_HINT_LOW_POWER) { + if (current_power_profile == PROFILE_POWER_SAVE) { + set_power_profile(PROFILE_BALANCED); + } else { + set_power_profile(PROFILE_POWER_SAVE); + } + } + + // Skip other hints in custom power modes + if (current_power_profile != PROFILE_BALANCED) { + return HINT_HANDLED; + } + + return HINT_NONE; +} + int set_interactive_override(struct power_module *module, int on) { char governor[80]; From d07d4f16985792d8641320926cad7fe50d5a3036 Mon Sep 17 00:00:00 2001 From: Zhao Wei Liew Date: Tue, 5 Jan 2016 08:27:20 +0800 Subject: [PATCH 18/23] power-8960: Remove set_interactive handling This is handled by the common powerHAL. Change-Id: I939743dd188b1d04793756e6ce9d7e6daefc468a --- power/power-8960.c | 40 ---------------------------------------- 1 file changed, 40 deletions(-) diff --git a/power/power-8960.c b/power/power-8960.c index b1103cd..db08425 100644 --- a/power/power-8960.c +++ b/power/power-8960.c @@ -48,8 +48,6 @@ #include "performance.h" #include "power-common.h" -static int display_hint_sent; - static int current_power_profile = PROFILE_BALANCED; static int is_8064 = -1; @@ -157,41 +155,3 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, return HINT_NONE; } - -int set_interactive_override(struct power_module *module, int on) -{ - char governor[80]; - - if (get_scaling_governor(governor, sizeof(governor)) == -1) { - ALOGE("Can't obtain scaling governor."); - - return HINT_NONE; - } - - if (!on) { - /* Display off. */ - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - int resource_values[] = {MS_500, THREAD_MIGRATION_SYNC_OFF}; - - if (!display_hint_sent) { - perform_hint_action(DISPLAY_STATE_HINT_ID, - resource_values, sizeof(resource_values)/sizeof(resource_values[0])); - display_hint_sent = 1; - } - - return HINT_HANDLED; - } - } else { - /* Display on */ - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - undo_hint_action(DISPLAY_STATE_HINT_ID); - display_hint_sent = 0; - - return HINT_HANDLED; - } - } - - return HINT_NONE; -} From 87a861847cd43892d1ead3904e18aed60d6ca2e0 Mon Sep 17 00:00:00 2001 From: Ethan Chen Date: Sun, 3 Jan 2016 14:52:58 -0800 Subject: [PATCH 19/23] power: Add support for 8952 * Original HAL: LA.BR.1.3.3_rb1.7 * Added CM profile, hinting support Change-Id: I331041f2639011a80d3f2752c62dccd6a1d0c0d6 --- power/Android.mk | 4 + power/power-8952.c | 261 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 265 insertions(+) create mode 100644 power/power-8952.c diff --git a/power/Android.mk b/power/Android.mk index 718004e..ac40171 100644 --- a/power/Android.mk +++ b/power/Android.mk @@ -41,6 +41,10 @@ ifeq ($(call is-board-platform-in-list, msm8916), true) LOCAL_SRC_FILES += power-8916.c endif +ifeq ($(call is-board-platform-in-list, msm8952), true) +LOCAL_SRC_FILES += power-8952.c +endif + ifeq ($(call is-board-platform-in-list, apq8084), true) LOCAL_SRC_FILES += power-8084.c endif diff --git a/power/power-8952.c b/power/power-8952.c new file mode 100644 index 0000000..a38218f --- /dev/null +++ b/power/power-8952.c @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LOG_NIDEBUG 0 + +#include +#include +#include +#include +#include +#include +#include + +#define LOG_TAG "QTI PowerHAL" +#include +#include +#include + +#include "utils.h" +#include "metadata-defs.h" +#include "hint-data.h" +#include "performance.h" +#include "power-common.h" + +#define ARRAY_SIZE(arr) (sizeof((arr)) / sizeof((arr)[0])) + +static int display_hint_sent; +static int video_encode_hint_sent; +static int current_power_profile = PROFILE_BALANCED; + +static void process_video_encode_hint(void *metadata); + +extern void interaction(int duration, int num_args, int opt_list[]); + +static int profile_high_performance_8952[11] = { + SCHED_BOOST_ON, + 0x704, 0x4d04, /* Enable all CPUs */ + CPU0_MIN_FREQ_TURBO_MAX, CPU1_MIN_FREQ_TURBO_MAX, + CPU2_MIN_FREQ_TURBO_MAX, CPU3_MIN_FREQ_TURBO_MAX, + CPU4_MIN_FREQ_TURBO_MAX, CPU5_MIN_FREQ_TURBO_MAX, + CPU6_MIN_FREQ_TURBO_MAX, CPU7_MIN_FREQ_TURBO_MAX, +}; + +static int profile_power_save_8952[5] = { + 0x8fe, 0x3dfd, /* 1 big core, 2 little cores*/ + CPUS_ONLINE_MAX_LIMIT_2, + CPU0_MAX_FREQ_NONTURBO_MAX, CPU1_MAX_FREQ_NONTURBO_MAX, + CPU2_MAX_FREQ_NONTURBO_MAX, CPU3_MAX_FREQ_NONTURBO_MAX, +}; + +int get_number_of_profiles() { + return 3; +} + +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_HIGH_PERFORMANCE) { + int *resource_values = profile_high_performance_8952; + perform_hint_action(DEFAULT_PROFILE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + ALOGD("%s: set performance mode", __func__); + + } else if (profile == PROFILE_POWER_SAVE) { + int *resource_values = profile_power_save_8952; + perform_hint_action(DEFAULT_PROFILE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + ALOGD("%s: set powersave", __func__); + } + + current_power_profile = profile; +} + +int power_hint_override(struct power_module *module, power_hint_t hint, + void *data) +{ + int duration; + int resources_launch_boost[] = { + SCHED_BOOST_ON, + 0x20f, + 0x101, + 0x3e01, + 0x4001, + 0x4101, + 0x4201, + }; + int resources_cpu_boost[] = { + SCHED_BOOST_ON, + 0x20d, + 0x3e01, + 0x101, + }; + + if (hint == POWER_HINT_SET_PROFILE) { + set_power_profile(*(int32_t *)data); + return HINT_HANDLED; + } + + // Skip other hints in custom power modes + if (current_power_profile != PROFILE_BALANCED) { + return HINT_HANDLED; + } + + switch (hint) { + case POWER_HINT_LAUNCH_BOOST: + duration = 2000; + interaction(duration, ARRAY_SIZE(resources_launch_boost), + resources_launch_boost); + return HINT_HANDLED; + case POWER_HINT_CPU_BOOST: + duration = *(int32_t *)data / 1000; + if (duration > 0) { + interaction(duration, ARRAY_SIZE(resources_cpu_boost), + resources_cpu_boost); + } + return HINT_HANDLED; + case POWER_HINT_VIDEO_ENCODE: + process_video_encode_hint(data); + return HINT_HANDLED; + } + return HINT_NONE; +} + +int set_interactive_override(struct power_module *module, int on) +{ + char governor[80]; + + ALOGI("Got set_interactive hint"); + + if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU0) == -1) { + if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU1) == -1) { + if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU2) == -1) { + if (get_scaling_governor_check_cores(governor, sizeof(governor),CPU3) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_HANDLED; + } + } + } + } + + if (!on) { + /* Display off. */ + if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && + (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + int resource_values[] = {TR_MS_CPU0_50, TR_MS_CPU4_50}; + + if (!display_hint_sent) { + perform_hint_action(DISPLAY_STATE_HINT_ID, + resource_values, ARRAY_SIZE(resource_values)); + display_hint_sent = 1; + } + } /* Perf time rate set for CORE0,CORE4 8952 target*/ + + } else { + /* Display on. */ + if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && + (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + + undo_hint_action(DISPLAY_STATE_HINT_ID); + display_hint_sent = 0; + } + } + return HINT_HANDLED; +} + +/* Video Encode Hint */ +static void process_video_encode_hint(void *metadata) +{ + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; + + ALOGI("Got process_video_encode_hint"); + + if (get_scaling_governor_check_cores(governor, + sizeof(governor),CPU0) == -1) { + if (get_scaling_governor_check_cores(governor, + sizeof(governor),CPU1) == -1) { + if (get_scaling_governor_check_cores(governor, + sizeof(governor),CPU2) == -1) { + if (get_scaling_governor_check_cores(governor, + sizeof(governor),CPU3) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_HANDLED; + } + } + } + } + + /* Initialize encode metadata struct fields. */ + memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); + video_encode_metadata.state = -1; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + + if (metadata) { + if (parse_video_encode_metadata((char *)metadata, + &video_encode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return; + } + } else { + return; + } + + if (video_encode_metadata.state == 1) { + if ((strncmp(governor, INTERACTIVE_GOVERNOR, + strlen(INTERACTIVE_GOVERNOR)) == 0) && + (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + int resource_values[] = {TR_MS_CPU0_30, TR_MS_CPU4_30}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, + resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + } + } + } else if (video_encode_metadata.state == 0) { + if ((strncmp(governor, INTERACTIVE_GOVERNOR, + strlen(INTERACTIVE_GOVERNOR)) == 0) && + (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + undo_hint_action(video_encode_metadata.hint_id); + video_encode_hint_sent = 0; + return ; + } + } + return; +} From 29a1035fd86f8c21ba6f9002097b6b539b1e206e Mon Sep 17 00:00:00 2001 From: Zhao Wei Liew Date: Tue, 12 Jan 2016 17:57:07 +0800 Subject: [PATCH 20/23] power: Remove custom low power mode hint handling The PerformanceManager code now handles the setting of powersave profile on low power mode, so this is redundant. This implementation also doesn't remember the previous user selected performance profile, instead only setting to balanced profile when low power mode is turned off. Change-Id: I5d65cd1e7b915e9a088523d2d62ae541b5bcd78c --- power/power-8084.c | 8 -------- power/power-8226.c | 8 -------- power/power-8610.c | 8 -------- power/power-8916.c | 8 -------- power/power-8960.c | 8 -------- power/power-8974.c | 8 -------- power/power-8994.c | 14 +------------- 7 files changed, 1 insertion(+), 61 deletions(-) diff --git a/power/power-8084.c b/power/power-8084.c index 2d33043..8c65f10 100644 --- a/power/power-8084.c +++ b/power/power-8084.c @@ -100,14 +100,6 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, return HINT_HANDLED; } - if (hint == POWER_HINT_LOW_POWER) { - if (current_power_profile == PROFILE_POWER_SAVE) { - set_power_profile(PROFILE_BALANCED); - } else { - set_power_profile(PROFILE_POWER_SAVE); - } - } - // Skip other hints in custom power modes if (current_power_profile != PROFILE_BALANCED) { return HINT_HANDLED; diff --git a/power/power-8226.c b/power/power-8226.c index 970392c..2cbfad6 100644 --- a/power/power-8226.c +++ b/power/power-8226.c @@ -97,14 +97,6 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, return HINT_HANDLED; } - if (hint == POWER_HINT_LOW_POWER) { - if (current_power_profile == PROFILE_POWER_SAVE) { - set_power_profile(PROFILE_BALANCED); - } else { - set_power_profile(PROFILE_POWER_SAVE); - } - } - // Skip other hints in custom power modes if (current_power_profile != PROFILE_BALANCED) { return HINT_HANDLED; diff --git a/power/power-8610.c b/power/power-8610.c index ed7c322..2e64083 100644 --- a/power/power-8610.c +++ b/power/power-8610.c @@ -95,14 +95,6 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, return HINT_HANDLED; } - if (hint == POWER_HINT_LOW_POWER) { - if (current_power_profile == PROFILE_POWER_SAVE) { - set_power_profile(PROFILE_BALANCED); - } else { - set_power_profile(PROFILE_POWER_SAVE); - } - } - // Skip other hints in custom power modes if (current_power_profile != PROFILE_BALANCED) { return HINT_HANDLED; diff --git a/power/power-8916.c b/power/power-8916.c index 6add9d0..55fdf3d 100644 --- a/power/power-8916.c +++ b/power/power-8916.c @@ -382,14 +382,6 @@ int power_hint_override(struct power_module *module __unused, power_hint_t hint, set_power_profile(*(int32_t *)data); } - if (hint == POWER_HINT_LOW_POWER) { - if (current_power_profile == PROFILE_POWER_SAVE) { - set_power_profile(PROFILE_BALANCED); - } else { - set_power_profile(PROFILE_POWER_SAVE); - } - } - // Skip other hints in custom power modes if (current_power_profile != PROFILE_BALANCED) { return HINT_HANDLED; diff --git a/power/power-8960.c b/power/power-8960.c index db08425..bfff734 100644 --- a/power/power-8960.c +++ b/power/power-8960.c @@ -140,14 +140,6 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, return HINT_HANDLED; } - if (hint == POWER_HINT_LOW_POWER) { - if (current_power_profile == PROFILE_POWER_SAVE) { - set_power_profile(PROFILE_BALANCED); - } else { - set_power_profile(PROFILE_POWER_SAVE); - } - } - // Skip other hints in custom power modes if (current_power_profile != PROFILE_BALANCED) { return HINT_HANDLED; diff --git a/power/power-8974.c b/power/power-8974.c index 5e726bd..b84b80b 100644 --- a/power/power-8974.c +++ b/power/power-8974.c @@ -114,14 +114,6 @@ int power_hint_override(__attribute__((unused)) struct power_module *module, return HINT_HANDLED; } - if (hint == POWER_HINT_LOW_POWER) { - if (current_power_profile == PROFILE_POWER_SAVE) { - set_power_profile(PROFILE_BALANCED); - } else { - set_power_profile(PROFILE_POWER_SAVE); - } - } - // Skip other hints in high/low power modes if (current_power_profile == PROFILE_POWER_SAVE || current_power_profile == PROFILE_HIGH_PERFORMANCE) { diff --git a/power/power-8994.c b/power/power-8994.c index 90a4f45..f98d6c6 100644 --- a/power/power-8994.c +++ b/power/power-8994.c @@ -54,7 +54,6 @@ int get_number_of_profiles() { } static int current_power_profile = PROFILE_BALANCED; -static int low_power_mode = 0; static void set_power_profile(int profile) { @@ -169,22 +168,11 @@ static int process_video_encode_hint(void *metadata) int power_hint_override(__attribute__((unused)) struct power_module *module, power_hint_t hint, void *data) { - if (hint == POWER_HINT_SET_PROFILE && !low_power_mode) { + if (hint == POWER_HINT_SET_PROFILE) { set_power_profile(*(int32_t *)data); return HINT_HANDLED; } - if (hint == POWER_HINT_LOW_POWER) { - if (low_power_mode) { - set_power_profile(PROFILE_BALANCED); - low_power_mode = 0; - } else { - set_power_profile(PROFILE_POWER_SAVE); - low_power_mode = 1; - } - return HINT_HANDLED; - } - // Skip other hints in custom power modes if (current_power_profile == PROFILE_POWER_SAVE || current_power_profile == PROFILE_HIGH_PERFORMANCE) { From 41354cb5728e71bb343cf85d27e0791e57c0a998 Mon Sep 17 00:00:00 2001 From: Zhao Wei Liew Date: Sun, 14 Feb 2016 21:59:08 +0800 Subject: [PATCH 21/23] power-8992: Add launch boost profile Change-Id: I51c8b7bdbf7030fce6e2e7a7a2c5c96dc2b4ccae --- power/power-8992.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/power/power-8992.c b/power/power-8992.c index d272841..4ce204c 100644 --- a/power/power-8992.c +++ b/power/power-8992.c @@ -103,7 +103,20 @@ static int process_video_encode_hint(void *metadata) int power_hint_override(struct power_module *module, power_hint_t hint, void *data) { int ret_val = HINT_NONE; + switch(hint) { + case POWER_HINT_LAUNCH_BOOST: + int duration = 2000; + int resources_launch_boost[] = { + SCHED_BOOST_ON, + 0x20D, + }; + + interaction(duration, ARRAY_SIZE(resources_launch_boost), + resources_launch_boost); + + ret_val = HINT_HANDLED; + break; case POWER_HINT_VIDEO_ENCODE: ret_val = process_video_encode_hint(data); break; From 053d0c33c1c843deb5963354214e092f6f796c79 Mon Sep 17 00:00:00 2001 From: Abhishek Arpure Date: Fri, 10 Apr 2015 15:16:44 -0700 Subject: [PATCH 22/23] init: Add msm8952-specific init extension library - Implements MSM-specific initialization during bootup - Sets the lcd density at the bootup Change-Id: I3f8bdbff0021405259fa1380c67313a750c7c512 common: Set system property to differentiate 8952 and 8956 hw Set system property to differentiate 8952 and 8956 hw based on soc-id to select appropriate media_codecs xml. Set system property to select correct media_profiles xml Change-Id: Ie6466fe65e9eab00a9f2cfe7810cf2ee44be1de2 common: add apq8056/76 soc ids to 8956/76 system property Add apq8056 and apq8076 soc ids along with msm8956/76 soc ids to the existing system property to enable it for apq chipsets as well. Change-Id: I6b0b19726c953d290aecf0e8ee358db136100835 init: get hardware version to support vp9 decoder on msm8956/76 msm8956/76 hardware version v1 supports vp9 decoder but version v0 does not. So read hardware version and do set_property to differentiate between version v0 and v1 for user space to use it when required. Change-Id: Ia0e4f69d7274a97fa2247be5dd58cb71d1fdf530 Rename init_msm8952.c to .cpp Change-Id: I5653f5c3bceb271b0c5c9590978a24c74e9286d7 --- init/init_msm8952.cpp | 119 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 init/init_msm8952.cpp diff --git a/init/init_msm8952.cpp b/init/init_msm8952.cpp new file mode 100644 index 0000000..a6ae854 --- /dev/null +++ b/init/init_msm8952.cpp @@ -0,0 +1,119 @@ +/* + Copyright (c) 2015, The Linux Foundation. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are + met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "vendor_init.h" +#include "property_service.h" +#include "log.h" +#include "util.h" + +#include "init_msm.h" + +#define VIRTUAL_SIZE "/sys/class/graphics/fb0/virtual_size" +#define VERSION "/sys/devices/soc.0/1d00000.qcom,vidc/version" +#define BUF_SIZE 64 + +int get_version(int *version) +{ + char buf[16]; + int pos = 0, rv = 0, fd = -1; + long value = 0; + char *endptr = NULL; + int bytes_to_read = sizeof(buf); + + fd = open(VERSION, O_RDONLY, 0660); + if (fd < 0) { + return -1; + } + + do { + pos += rv; + if ((bytes_to_read - pos) <= 0) + break; + rv += read(fd, buf + pos, bytes_to_read - pos); + } while (rv > 0); + + if (rv < 0) { + return -1; + } + buf[pos - 1] = '\0'; + value = strtol(buf, &endptr, sizeof(long)); + if (endptr == buf) { + return -1; + } + *version = (int)value; + + return 1; +} + +void init_msm_properties(unsigned long msm_id, unsigned long msm_ver, char *board_type) +{ + char platform[PROP_VALUE_MAX]; + int rc; + int version = 0; + unsigned long virtual_size = 0; + char str[BUF_SIZE]; + + UNUSED(msm_id); + UNUSED(msm_ver); + UNUSED(board_type); + + rc = property_get("ro.board.platform", platform); + if (!rc || !ISMATCH(platform, ANDROID_TARGET)){ + return; + } + + rc = read_file2(VIRTUAL_SIZE, str, sizeof(str)); + if (rc) { + virtual_size = strtoul(str, NULL, 0); + } + + if(virtual_size >= 1080) { + property_set(PROP_LCDDENSITY, "480"); + } else if (virtual_size >= 720) { + // For 720x1280 resolution + property_set(PROP_LCDDENSITY, "320"); + } else if (virtual_size >= 480) { + // For 480x854 resolution QRD. + property_set(PROP_LCDDENSITY, "240"); + } else + property_set(PROP_LCDDENSITY, "320"); + + if (msm_id == 266 || msm_id == 278 || msm_id == 277 || msm_id == 274) { + property_set("media.msm8956hw", "1"); + property_set("media.settings.xml", "/etc/media_profiles_8956.xml"); + get_version(&version); + if (version == 1) + property_set("media.msm8956.version", "1"); + else + property_set("media.msm8956.version", "0"); + } +} From da3c30e75a659d5e6cb952c084f2eab072b12a08 Mon Sep 17 00:00:00 2001 From: Zhao Wei Liew Date: Sun, 21 Feb 2016 07:48:02 +0800 Subject: [PATCH 23/23] power-8992: Fix build error and warnings Caused partially by change-id I51c8b7bdbf7030fce6e2e7a7a2c5c96dc2b4ccae Change-Id: I1e64060e5759b543760e5e015179003f36e46980 --- power/power-8992.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/power/power-8992.c b/power/power-8992.c index 4ce204c..8f855be 100644 --- a/power/power-8992.c +++ b/power/power-8992.c @@ -47,8 +47,12 @@ #include "performance.h" #include "power-common.h" +#define ARRAY_SIZE(arr) (sizeof((arr)) / sizeof((arr)[0])) + static int display_hint_sent; +extern void interaction(int duration, int num_args, int opt_list[]); + static int process_video_encode_hint(void *metadata) { char governor[80]; @@ -100,18 +104,19 @@ static int process_video_encode_hint(void *metadata) return HINT_NONE; } -int power_hint_override(struct power_module *module, power_hint_t hint, void *data) +int power_hint_override(__attribute__((unused)) struct power_module *module, + power_hint_t hint, void *data) { int ret_val = HINT_NONE; + int duration; + int resources_launch_boost[] = { + SCHED_BOOST_ON, + 0x20D, + }; switch(hint) { case POWER_HINT_LAUNCH_BOOST: - int duration = 2000; - int resources_launch_boost[] = { - SCHED_BOOST_ON, - 0x20D, - }; - + duration = 2000; interaction(duration, ARRAY_SIZE(resources_launch_boost), resources_launch_boost); @@ -126,7 +131,7 @@ int power_hint_override(struct power_module *module, power_hint_t hint, void *da return ret_val; } -int set_interactive_override(struct power_module *module, int on) +int set_interactive_override(__attribute__((unused)) struct power_module *module, int on) { char governor[80];