From e032e7cc781d8772a763b625decf8592df5d2323 Mon Sep 17 00:00:00 2001 From: LuK1337 Date: Tue, 23 Jun 2020 14:43:35 +0200 Subject: [PATCH] sm8250-common: power: Rebase on LA.UM.8.12.r1-11900-sm8250.0 --- common.mk | 2 +- power/.clang-format | 11 - power/Android.mk | 57 ++- power/NOTICE | 32 ++ power/Power.cpp | 111 +++++ power/Power.h | 74 +++ power/android.hardware.power@1.2-service.rc | 4 + power/hint-data.c | 13 +- power/hint-data.h | 54 ++- power/list.c | 44 +- power/list.h | 18 +- power/metadata-defs.h | 14 +- power/metadata-parser.c | 65 ++- power/performance.h | 26 +- power/power-845.c | 273 ----------- power/power-common.c | 135 ++++++ power/power-common.h | 29 +- power/power.c | 506 -------------------- power/powerhintparser.c | 102 ++-- power/powerhintparser.h | 8 +- power/service.cpp | 81 ++++ power/utils.c | 178 ++++--- power/utils.h | 12 +- sepolicy/private/file_contexts | 1 + 24 files changed, 800 insertions(+), 1050 deletions(-) delete mode 100644 power/.clang-format create mode 100644 power/NOTICE create mode 100644 power/Power.cpp create mode 100644 power/Power.h create mode 100644 power/android.hardware.power@1.2-service.rc delete mode 100644 power/power-845.c create mode 100644 power/power-common.c delete mode 100644 power/power.c create mode 100644 power/service.cpp diff --git a/common.mk b/common.mk index 83cd038..5ab9df0 100644 --- a/common.mk +++ b/common.mk @@ -158,7 +158,7 @@ PRODUCT_PACKAGES += \ # Power PRODUCT_PACKAGES += \ - power.qcom:64 + android.hardware.power@1.2-service.oneplus_kona # Ramdisk PRODUCT_COPY_FILES += \ diff --git a/power/.clang-format b/power/.clang-format deleted file mode 100644 index ae4a451..0000000 --- a/power/.clang-format +++ /dev/null @@ -1,11 +0,0 @@ -BasedOnStyle: Google -AccessModifierOffset: -2 -AllowShortFunctionsOnASingleLine: Inline -ColumnLimit: 100 -CommentPragmas: NOLINT:.* -DerivePointerAlignment: false -IndentWidth: 4 -PointerAlignment: Left -TabWidth: 4 -UseTab: Never -PenaltyExcessCharacter: 32 diff --git a/power/Android.mk b/power/Android.mk index a02cd4a..2468996 100644 --- a/power/Android.mk +++ b/power/Android.mk @@ -2,27 +2,60 @@ LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) -LOCAL_MODULE := power.qcom -LOCAL_MODULE_PATH_32 := $(TARGET_OUT_PRODUCT)/vendor_overlay/$(PRODUCT_TARGET_VNDK_VERSION)/lib -LOCAL_MODULE_PATH_64 := $(TARGET_OUT_PRODUCT)/vendor_overlay/$(PRODUCT_TARGET_VNDK_VERSION)/lib64 +LOCAL_MODULE := android.hardware.power@1.2-service.oneplus_kona +LOCAL_MODULE_TAGS := optional + +LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/vendor_overlay/$(PRODUCT_TARGET_VNDK_VERSION)/bin LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_STEM := android.hardware.power@1.2-service + +LOCAL_CFLAGS += \ + -Wno-unused-parameter \ + -Wno-unused-variable + +LOCAL_C_INCLUDES := \ + external/libxml2/include \ + external/icu/icu4c/source/common + +LOCAL_HEADER_LIBRARIES += \ + libhardware_headers \ + libutils_headers LOCAL_SRC_FILES := \ hint-data.c \ list.c \ metadata-parser.c \ - power-845.c \ - power.c \ + power-common.c \ + Power.cpp \ powerhintparser.c \ + service.cpp \ utils.c -LOCAL_C_INCLUDES := external/libxml2/include \ - external/icu/icu4c/source/common +LOCAL_REQUIRED_MODULES := \ + android.hardware.power@1.2-service.oneplus_kona.rc -LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libxml2 +LOCAL_SHARED_LIBRARIES := \ + android.hardware.power@1.2 \ + libbase \ + libcutils \ + libdl \ + libhidlbase \ + libhidltransport \ + liblog \ + libutils \ + libxml2 -LOCAL_CFLAGS += -Werror -Wall -Wno-unused-parameter -LOCAL_CFLAGS += -DINTERACTION_BOOST +include $(BUILD_EXECUTABLE) -include $(BUILD_SHARED_LIBRARY) +include $(CLEAR_VARS) + +LOCAL_MODULE := android.hardware.power@1.2-service.oneplus_kona.rc +LOCAL_MODULE_TAGS := optional +LOCAL_MODULE_CLASS := ETC + +LOCAL_MODULE_PATH := $(TARGET_OUT_PRODUCT)/vendor_overlay/$(PRODUCT_TARGET_VNDK_VERSION)/etc/init +LOCAL_MODULE_STEM := android.hardware.power@1.2-service.rc + +LOCAL_SRC_FILES := android.hardware.power@1.2-service.rc + +include $(BUILD_PREBUILT) diff --git a/power/NOTICE b/power/NOTICE new file mode 100644 index 0000000..26f0cc8 --- /dev/null +++ b/power/NOTICE @@ -0,0 +1,32 @@ +Copyright (c) 2012-2017, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted (subject to the limitations in the +disclaimer below) 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. + +NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE +GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT +HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER 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. + diff --git a/power/Power.cpp b/power/Power.cpp new file mode 100644 index 0000000..ac28844 --- /dev/null +++ b/power/Power.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019, 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_TAG "QTI PowerHAL" + +#include +#include +#include +#include "Power.h" +#include "power-common.h" + +namespace android { +namespace hardware { +namespace power { +namespace V1_2 { +namespace implementation { + +using ::android::base::WriteStringToFile; +using ::android::hardware::power::V1_0::Feature; +using ::android::hardware::power::V1_0::PowerHint; +using ::android::hardware::power::V1_0::PowerStatePlatformSleepState; +using ::android::hardware::power::V1_0::Status; +using ::android::hardware::power::V1_1::PowerStateSubsystem; +using ::android::hardware::hidl_vec; +using ::android::hardware::Return; +using ::android::hardware::Void; + +Power::Power() { + power_init(); +} + +Return Power::setInteractive(bool interactive) { + set_interactive(interactive ? 1:0); + return Void(); +} + +Return Power::powerHint(PowerHint_1_0 hint, int32_t data) { + + power_hint(static_cast(hint), data ? (&data) : NULL); + return Void(); +} + +Return Power::setFeature(Feature feature, bool activate) { + switch (feature) { + case Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE: + WriteStringToFile(activate ? "1" : "0", "/proc/touchpanel/double_tap_enable", true); + break; + default: + break; + } + return Void(); +} + +Return Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) { + + hidl_vec states; + states.resize(0); + + _hidl_cb(states, Status::SUCCESS); + return Void(); +} + +Return Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) { + + hidl_vec subsystems; + + _hidl_cb(subsystems, Status::SUCCESS); + return Void(); +} + +Return Power::powerHintAsync(PowerHint_1_0 hint, int32_t data) { + + return powerHint(hint, data); +} + +Return Power::powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) { + + return powerHint(static_cast (hint), data); +} + +} // namespace implementation +} // namespace V1_2 +} // namespace power +} // namespace hardware +} // namespace android diff --git a/power/Power.h b/power/Power.h new file mode 100644 index 0000000..a787590 --- /dev/null +++ b/power/Power.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2019, 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. + */ + +#ifndef ANDROID_HARDWARE_POWER_V1_2_POWER_H +#define ANDROID_HARDWARE_POWER_V1_2_POWER_H + +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace power { +namespace V1_2 { +namespace implementation { + +using ::android::hardware::power::V1_0::Feature; +using PowerHint_1_0 = ::android::hardware::power::V1_0::PowerHint; +using PowerHint_1_2 = ::android::hardware::power::V1_2::PowerHint; +using ::android::hardware::power::V1_2::IPower; +using ::android::hardware::Return; +using ::android::hardware::Void; + +struct Power : public IPower { + // Methods from ::android::hardware::power::V1_0::IPower follow. + + Power(); + + Return setInteractive(bool interactive) override; + Return powerHint(PowerHint_1_0 hint, int32_t data) override; + Return setFeature(Feature feature, bool activate) override; + Return getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) override; + + // Methods from ::android::hardware::power::V1_1::IPower follow + Return getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) override; + Return powerHintAsync(PowerHint_1_0 hint, int32_t data) override; + // Methods from ::android::hardware::power::V1_2::IPower follow + Return powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) override; +}; + +} // namespace implementation +} // namespace V1_2 +} // namespace power +} // namespace hardware +} // namespace android + +#endif // ANDROID_HARDWARE_POWER_V1_2_POWER_H diff --git a/power/android.hardware.power@1.2-service.rc b/power/android.hardware.power@1.2-service.rc new file mode 100644 index 0000000..8a1c347 --- /dev/null +++ b/power/android.hardware.power@1.2-service.rc @@ -0,0 +1,4 @@ +service vendor.power-hal-1-2 /vendor/bin/hw/android.hardware.power@1.2-service + class hal + user system + group system diff --git a/power/hint-data.c b/power/hint-data.c index f621dd7..67da77a 100644 --- a/power/hint-data.c +++ b/power/hint-data.c @@ -27,20 +27,21 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include - #include "hint-data.h" -int hint_compare(struct hint_data* first_hint, struct hint_data* other_hint) { +int hint_compare(struct hint_data *first_hint, + struct hint_data *other_hint) { if (first_hint == other_hint) { return 0; - } else if ((first_hint && other_hint) && (first_hint->hint_id == other_hint->hint_id)) { + } else if ((first_hint && other_hint) && + (first_hint->hint_id == other_hint->hint_id)) { return 0; } else { return 1; } } -void hint_dump(struct hint_data* hint) { - ALOGI("hint_id: %lu", hint->hint_id); +void hint_dump(struct hint_data *hint) +{ + /*ALOGI("hint_id: %lu", hint->hint_id);*/ } diff --git a/power/hint-data.h b/power/hint-data.h index 22b98d9..48909c7 100644 --- a/power/hint-data.h +++ b/power/hint-data.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2013, 2015, 2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012, 2013, 2015, 2017-2018, 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 @@ -28,34 +28,42 @@ */ /* Default use-case hint IDs */ -#define DEFAULT_VIDEO_ENCODE_HINT_ID (0x0A00) -#define DEFAULT_VIDEO_DECODE_HINT_ID (0x0B00) -#define DISPLAY_STATE_HINT_ID (0x0C00) -#define DISPLAY_STATE_HINT_ID_2 (0x0D00) -#define CAM_PREVIEW_HINT_ID (0x0E00) -#define SUSTAINED_PERF_HINT_ID (0x0F00) -#define VR_MODE_HINT_ID (0x1000) -#define VR_MODE_SUSTAINED_PERF_HINT_ID (0x1001) -#define INTERACTION_HINT_ID (0x1A00) +#define DEFAULT_VIDEO_ENCODE_HINT_ID (0x0A00) +#define DEFAULT_VIDEO_DECODE_HINT_ID (0x0B00) +#define DISPLAY_STATE_HINT_ID (0x0C00) +#define DISPLAY_STATE_HINT_ID_2 (0x0D00) +#define CAM_PREVIEW_HINT_ID (0x0E00) +#define SUSTAINED_PERF_HINT_ID (0x0F00) +#define VR_MODE_HINT_ID (0x1000) +#define VR_MODE_SUSTAINED_PERF_HINT_ID (0x1001) -#define AOSP_DELTA (0x1200) +#define AOSP_DELTA (0x1200) -#define VSYNC_HINT AOSP_DELTA + POWER_HINT_VSYNC -#define INTERACTION_HINT AOSP_DELTA + POWER_HINT_INTERACTION -#define VIDEO_DECODE_HINT AOSP_DELTA + POWER_HINT_VIDEO_DECODE -#define VIDEO_ENCODE_HINT AOSP_DELTA + POWER_HINT_VIDEO_ENCODE -#define LOW_POWER_HINT AOSP_DELTA + POWER_HINT_LOW_POWER -#define SUSTAINED_PERF_HINT AOSP_DELTA + POWER_HINT_SUSTAINED_PERFORMANCE -#define VR_MODE_HINT AOSP_DELTA + POWER_HINT_VR_MODE -#define LAUNCH_HINT AOSP_DELTA + POWER_HINT_LAUNCH -#define DISABLE_TOUCH_HINT AOSP_DELTA + POWER_HINT_DISABLE_TOUCH +#define VSYNC_HINT AOSP_DELTA + POWER_HINT_VSYNC +#define INTERACTION_HINT AOSP_DELTA + POWER_HINT_INTERACTION +#define VIDEO_DECODE_HINT AOSP_DELTA + POWER_HINT_VIDEO_DECODE +#define VIDEO_ENCODE_HINT AOSP_DELTA + POWER_HINT_VIDEO_ENCODE +#define LOW_POWER_HINT AOSP_DELTA + POWER_HINT_LOW_POWER +#define SUSTAINED_PERF_HINT AOSP_DELTA + POWER_HINT_SUSTAINED_PERFORMANCE +#define VR_MODE_HINT AOSP_DELTA + POWER_HINT_VR_MODE +#define LAUNCH_HINT AOSP_DELTA + POWER_HINT_LAUNCH +#define DISABLE_TOUCH_HINT AOSP_DELTA + POWER_HINT_DISABLE_TOUCH -#define VR_MODE_SUSTAINED_PERF_HINT (0x1301) +//update NUM_HINTS if hints are added to AOSP +#define NUM_HINTS (POWER_HINT_DISABLE_TOUCH +1) + +#define VR_MODE_SUSTAINED_PERF_HINT (0x1301) + +struct hint_handles{ + int handle; + int ref_count; +}; struct hint_data { unsigned long hint_id; /* This is our key. */ unsigned long perflock_handle; }; -int hint_compare(struct hint_data* first_hint, struct hint_data* other_hint); -void hint_dump(struct hint_data* hint); +int hint_compare(struct hint_data *first_hint, + struct hint_data *other_hint); +void hint_dump(struct hint_data *hint); diff --git a/power/list.c b/power/list.c index b3b987c..0fe8de2 100644 --- a/power/list.c +++ b/power/list.c @@ -31,20 +31,23 @@ #include #include -#include #include "list.h" +#include -int init_list_head(struct list_node* head) { - if (head == NULL) return -1; +int init_list_head(struct list_node *head) +{ + if (head == NULL) + return -1; memset(head, 0, sizeof(*head)); return 0; } -struct list_node* add_list_node(struct list_node* head, void* data) { +struct list_node *add_list_node(struct list_node *head, void *data) +{ /* Create a new list_node. And put 'data' into it. */ - struct list_node* new_node; + struct list_node *new_node; if (head == NULL) { return NULL; @@ -63,16 +66,18 @@ struct list_node* add_list_node(struct list_node* head, void* data) { return new_node; } -int is_list_empty(struct list_node* head) { +int is_list_empty(struct list_node *head) +{ return (head == NULL || head->next == NULL); } /* * Delink and de-allocate 'node'. */ -int remove_list_node(struct list_node* head, struct list_node* del_node) { - struct list_node* current_node; - struct list_node* saved_node; +int remove_list_node(struct list_node *head, struct list_node *del_node) +{ + struct list_node *current_node; + struct list_node *saved_node; if (head == NULL || head->next == NULL) { return -1; @@ -102,12 +107,14 @@ int remove_list_node(struct list_node* head, struct list_node* del_node) { return 0; } -void dump_list(struct list_node* head) { - struct list_node* current_node = head; +void dump_list(struct list_node *head) +{ + struct list_node *current_node = head; - if (head == NULL) return; + if (head == NULL) + return; - ALOGV("List:\n"); + printf("List:\n"); while ((current_node = current_node->next)) { if (current_node->dump) { @@ -116,14 +123,17 @@ void dump_list(struct list_node* head) { } } -struct list_node* find_node(struct list_node* head, void* comparison_data) { - struct list_node* current_node = head; +struct list_node *find_node(struct list_node *head, void *comparison_data) +{ + struct list_node *current_node = head; - if (head == NULL) return NULL; + if (head == NULL) + return NULL; while ((current_node = current_node->next)) { if (current_node->compare) { - if (current_node->compare(current_node->data, comparison_data) == 0) { + if (current_node->compare(current_node->data, + comparison_data) == 0) { /* Match found. Return current_node. */ return current_node; } diff --git a/power/list.h b/power/list.h index 6e81d98..d68c3df 100644 --- a/power/list.h +++ b/power/list.h @@ -28,14 +28,14 @@ */ struct list_node { - struct list_node* next; - void* data; - int (*compare)(void* data1, void* data2); - void (*dump)(void* data); + struct list_node *next; + void *data; + int (*compare)(void *data1, void *data2); + void (*dump)(void *data); }; -int init_list_head(struct list_node* head); -struct list_node* add_list_node(struct list_node* head, void* data); -int remove_list_node(struct list_node* head, struct list_node* del_node); -void dump_list(struct list_node* head); -struct list_node* find_node(struct list_node* head, void* comparison_data); +int init_list_head(struct list_node *head); +struct list_node * add_list_node(struct list_node *head, void *data); +int remove_list_node(struct list_node *head, struct list_node *del_node); +void dump_list(struct list_node *head); +struct list_node *find_node(struct list_node *head, void *comparison_data); diff --git a/power/metadata-defs.h b/power/metadata-defs.h index bbc5fbf..c464900 100644 --- a/power/metadata-defs.h +++ b/power/metadata-defs.h @@ -34,7 +34,7 @@ #define METADATA_PARSING_CONTINUE (0) #define METADATA_PARSING_DONE (1) -#define MIN(x, y) (((x) > (y)) ? (y) : (x)) +#define MIN(x,y) (((x)>(y))?(y):(x)) struct video_encode_metadata_t { int hint_id; @@ -46,9 +46,9 @@ struct video_decode_metadata_t { int state; }; -int parse_metadata(char* metadata, char** metadata_saveptr, char* attribute, - unsigned int attribute_size, char* value, unsigned int value_size); -int parse_video_encode_metadata(char* metadata, - struct video_encode_metadata_t* video_encode_metadata); -int parse_video_decode_metadata(char* metadata, - struct video_decode_metadata_t* video_decode_metadata); +int parse_metadata(char *metadata, char **metadata_saveptr, + char *attribute, int attribute_size, char *value, int value_size); +int parse_video_encode_metadata(char *metadata, + struct video_encode_metadata_t *video_encode_metadata); +int parse_video_decode_metadata(char *metadata, + struct video_decode_metadata_t *video_decode_metadata); diff --git a/power/metadata-parser.c b/power/metadata-parser.c index 4a8bc30..c9122a4 100644 --- a/power/metadata-parser.c +++ b/power/metadata-parser.c @@ -28,43 +28,55 @@ */ #include -#include #include +#include #include "metadata-defs.h" -int parse_metadata(char* metadata, char** metadata_saveptr, char* attribute, - unsigned int attribute_size, char* value, unsigned int value_size) { - char* attribute_string; - char* attribute_value_delim; +int parse_metadata(char *metadata, char **metadata_saveptr, + char *attribute, int attribute_size, char *value, int value_size) +{ + char *attribute_string; + char *attribute_value_delim; unsigned int bytes_to_copy; - attribute_string = strtok_r(metadata, ATTRIBUTE_STRING_DELIM, metadata_saveptr); + attribute_string = strtok_r(metadata, ATTRIBUTE_STRING_DELIM, + metadata_saveptr); - if (attribute_string == NULL) return METADATA_PARSING_DONE; + if (attribute_string == NULL) + return METADATA_PARSING_DONE; attribute[0] = value[0] = '\0'; - if ((attribute_value_delim = strchr(attribute_string, ATTRIBUTE_VALUE_DELIM)) != NULL) { - unsigned int attribute_len = (unsigned int)(attribute_value_delim - attribute_string); - /* copy only attribute len + NUL character, or as much as can be fit */ - bytes_to_copy = MIN(attribute_len + 1, attribute_size); + if ((attribute_value_delim = strchr(attribute_string, + ATTRIBUTE_VALUE_DELIM)) != NULL) { + bytes_to_copy = MIN((attribute_value_delim - attribute_string), + attribute_size - 1); + /* Replace strncpy with strlcpy + * Add +1 to bytes_to_copy as strlcpy copies size-1 bytes */ + strlcpy(attribute, attribute_string, + bytes_to_copy+1); - strlcpy(attribute, attribute_string, bytes_to_copy); - strlcpy(value, attribute_value_delim + 1, value_size); + bytes_to_copy = MIN(strlen(attribute_string) - strlen(attribute) - 1, + value_size - 1); + /* Replace strncpy with strlcpy + * Add +1 to bytes_to_copy as strlcpy copies size-1 bytes */ + strlcpy(value, attribute_value_delim + 1, + bytes_to_copy+1); } return METADATA_PARSING_CONTINUE; } -int parse_video_encode_metadata(char* metadata, - struct video_encode_metadata_t* video_encode_metadata) { +int parse_video_encode_metadata(char *metadata, + struct video_encode_metadata_t *video_encode_metadata) +{ char attribute[1024], value[1024], *saveptr; - char* temp_metadata = metadata; + char *temp_metadata = metadata; int parsing_status; - while ((parsing_status = parse_metadata(temp_metadata, &saveptr, attribute, sizeof(attribute), - value, sizeof(value))) == METADATA_PARSING_CONTINUE) { + while ((parsing_status = parse_metadata(temp_metadata, &saveptr, + attribute, sizeof(attribute), value, sizeof(value))) == METADATA_PARSING_CONTINUE) { if (strlen(attribute) == strlen("hint_id") && (strncmp(attribute, "hint_id", strlen("hint_id")) == 0)) { if (strlen(value) > 0) { @@ -82,19 +94,21 @@ int parse_video_encode_metadata(char* metadata, temp_metadata = NULL; } - if (parsing_status == METADATA_PARSING_ERR) return -1; + if (parsing_status == METADATA_PARSING_ERR) + return -1; return 0; } -int parse_video_decode_metadata(char* metadata, - struct video_decode_metadata_t* video_decode_metadata) { +int parse_video_decode_metadata(char *metadata, + struct video_decode_metadata_t *video_decode_metadata) +{ char attribute[1024], value[1024], *saveptr; - char* temp_metadata = metadata; + char *temp_metadata = metadata; int parsing_status; - while ((parsing_status = parse_metadata(temp_metadata, &saveptr, attribute, sizeof(attribute), - value, sizeof(value))) == METADATA_PARSING_CONTINUE) { + while ((parsing_status = parse_metadata(temp_metadata, &saveptr, + attribute, sizeof(attribute), value, sizeof(value))) == METADATA_PARSING_CONTINUE) { if (strlen(attribute) == strlen("hint_id") && (strncmp(attribute, "hint_id", strlen("hint_id")) == 0)) { if (strlen(value) > 0) { @@ -112,7 +126,8 @@ int parse_video_decode_metadata(char* metadata, temp_metadata = NULL; } - if (parsing_status == METADATA_PARSING_ERR) return -1; + if (parsing_status == METADATA_PARSING_ERR) + return -1; return 0; } diff --git a/power/performance.h b/power/performance.h index cfa585d..b7bf34b 100644 --- a/power/performance.h +++ b/power/performance.h @@ -31,31 +31,15 @@ extern "C" { #endif -#define FAILED -1 -#define SUCCESS 0 -#define INDEFINITE_DURATION 0 +#define FAILED -1 +#define SUCCESS 0 +#define INDEFINITE_DURATION 0 /* Hints sent to perf HAL from power HAL * These have to be kept in sync with Perf HAL side definitions */ -#define VENDOR_HINT_DISPLAY_OFF 0x00001040 -#define VENDOR_HINT_DISPLAY_ON 0x00001041 - -#define VENDOR_HINT_FIRST_LAUNCH_BOOST 0x00001081 -#define VENDOR_HINT_SCROLL_BOOST 0x00001080 - -enum { - LAUNCH_BOOST_V1 = 1, - LAUNCH_BOOST_V2 = 2, - LAUNCH_BOOST_V3 = 3 -}; - -enum { - SCROLL_VERTICAL = 1, - SCROLL_HORIZONTAL = 2, - SCROLL_PANEL_VIEW = 3, - SCROLL_PREFILING = 4 -}; +#define VENDOR_HINT_DISPLAY_OFF 0x00001040 +#define VENDOR_HINT_DISPLAY_ON 0x00001041 enum SCREEN_DISPLAY_TYPE { DISPLAY_OFF = 0x00FF, diff --git a/power/power-845.c b/power/power-845.c deleted file mode 100644 index b576bab..0000000 --- a/power/power-845.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2017, 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 "hint-data.h" -#include "metadata-defs.h" -#include "performance.h" -#include "power-common.h" -#include "utils.h" - -#define CHECK_HANDLE(x) ((x) > 0) -#define NUM_PERF_MODES 3 - -const int kMaxInteractiveDuration = 5000; /* ms */ -const int kMinInteractiveDuration = 100; /* ms */ -const int kMinFlingDuration = 1500; /* ms */ - -typedef enum { - NORMAL_MODE = 0, - SUSTAINED_MODE = 1, - VR_MODE = 2, - VR_SUSTAINED_MODE = (SUSTAINED_MODE | VR_MODE), - INVALID_MODE = 0xFF -} perf_mode_type_t; - -typedef struct perf_mode { - perf_mode_type_t type; - int perf_hint_id; -} perf_mode_t; - -perf_mode_t perf_modes[NUM_PERF_MODES] = {{SUSTAINED_MODE, SUSTAINED_PERF_HINT}, - {VR_MODE, VR_MODE_HINT}, - {VR_SUSTAINED_MODE, VR_MODE_SUSTAINED_PERF_HINT}}; - -static pthread_mutex_t perf_mode_switch_lock = PTHREAD_MUTEX_INITIALIZER; -static int current_mode = NORMAL_MODE; - -static inline int get_perfd_hint_id(perf_mode_type_t type) { - int i; - for (i = 0; i < NUM_PERF_MODES; i++) { - if (perf_modes[i].type == type) { - ALOGD("Hint id is 0x%x for mode 0x%x", perf_modes[i].perf_hint_id, type); - return perf_modes[i].perf_hint_id; - } - } - ALOGD("Couldn't find the hint for mode 0x%x", type); - return 0; -} - -static int switch_mode(perf_mode_type_t mode) { - int hint_id = 0; - static int perfd_mode_handle = -1; - - // release existing mode if any - if (CHECK_HANDLE(perfd_mode_handle)) { - ALOGD("Releasing handle 0x%x", perfd_mode_handle); - release_request(perfd_mode_handle); - perfd_mode_handle = -1; - } - // switch to a perf mode - hint_id = get_perfd_hint_id(mode); - if (hint_id != 0) { - perfd_mode_handle = perf_hint_enable(hint_id, 0); - if (!CHECK_HANDLE(perfd_mode_handle)) { - ALOGE("Failed perf_hint_interaction for mode: 0x%x", mode); - return -1; - } - ALOGD("Acquired handle 0x%x", perfd_mode_handle); - } - return 0; -} - -static int process_perf_hint(void* data, perf_mode_type_t mode) { - pthread_mutex_lock(&perf_mode_switch_lock); - - // enable - if (data) { - ALOGI("Enable request for mode: 0x%x", mode); - // check if mode is current mode - if (current_mode & mode) { - pthread_mutex_unlock(&perf_mode_switch_lock); - ALOGD("Mode 0x%x already enabled", mode); - return HINT_HANDLED; - } - // enable requested mode - if (0 != switch_mode(current_mode | mode)) { - pthread_mutex_unlock(&perf_mode_switch_lock); - ALOGE("Couldn't enable mode 0x%x", mode); - return HINT_NONE; - } - current_mode |= mode; - ALOGI("Current mode is 0x%x", current_mode); - // disable - } else { - ALOGI("Disable request for mode: 0x%x", mode); - // check if mode is enabled - if (!(current_mode & mode)) { - pthread_mutex_unlock(&perf_mode_switch_lock); - ALOGD("Mode 0x%x already disabled", mode); - return HINT_HANDLED; - } - // disable requested mode - if (0 != switch_mode(current_mode & ~mode)) { - pthread_mutex_unlock(&perf_mode_switch_lock); - ALOGE("Couldn't disable mode 0x%x", mode); - return HINT_NONE; - } - current_mode &= ~mode; - ALOGI("Current mode is 0x%x", current_mode); - } - - pthread_mutex_unlock(&perf_mode_switch_lock); - return HINT_HANDLED; -} - -static int process_video_encode_hint(void* metadata) { - char governor[80]; - struct video_encode_metadata_t video_encode_metadata; - static int video_encode_handle = 0; - - if (!metadata) return HINT_NONE; - - if (get_scaling_governor(governor, sizeof(governor)) == -1) { - ALOGE("Can't obtain scaling governor."); - - return HINT_NONE; - } - - /* Initialize encode metadata struct fields */ - memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t)); - video_encode_metadata.state = -1; - - if (parse_video_encode_metadata((char*)metadata, &video_encode_metadata) == -1) { - ALOGE("Error occurred while parsing metadata."); - return HINT_NONE; - } - - if (video_encode_metadata.state == 1) { - if (is_interactive_governor(governor)) { - video_encode_handle = perf_hint_enable(VIDEO_ENCODE_HINT, 0); - ALOGI("Video encode hint start"); - return HINT_HANDLED; - } - } else if (video_encode_metadata.state == 0) { - if (is_interactive_governor(governor)) { - release_request(video_encode_handle); - ALOGI("Video Encode hint stop"); - return HINT_HANDLED; - } - } - return HINT_NONE; -} - -static int process_activity_launch_hint(void* data) { - if (current_mode != NORMAL_MODE) { - ALOGV("%s: ignoring due to other active perf hints", __func__); - } else { - perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST, -1, LAUNCH_BOOST_V1); - } - return HINT_HANDLED; -} - -static int process_interaction_hint(void* data) { - static struct timespec s_previous_boost_timespec; - static int s_previous_duration = 0; - - struct timespec cur_boost_timespec; - long long elapsed_time; - int duration = kMinInteractiveDuration; - - if (current_mode != NORMAL_MODE) { - ALOGV("%s: ignoring due to other active perf hints", __func__); - return HINT_HANDLED; - } - - if (data) { - int input_duration = *((int*)data); - if (input_duration > duration) { - duration = (input_duration > kMaxInteractiveDuration) ? - kMaxInteractiveDuration : input_duration; - } - } - - clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); - - elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); - // don't hint if previous hint's duration covers this hint's duration - if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) { - return HINT_HANDLED; - } - s_previous_boost_timespec = cur_boost_timespec; - s_previous_duration = duration; - - if (duration >= kMinFlingDuration) { - perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, -1, SCROLL_PREFILING); - } else { - perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL); - } - return HINT_HANDLED; -} - -int power_hint_override(struct power_module* module, power_hint_t hint, void* data) { - int ret_val = HINT_NONE; - switch (hint) { - case POWER_HINT_VIDEO_ENCODE: - ret_val = process_video_encode_hint(data); - break; - case POWER_HINT_SUSTAINED_PERFORMANCE: - ret_val = process_perf_hint(data, SUSTAINED_MODE); - break; - case POWER_HINT_VR_MODE: - ret_val = process_perf_hint(data, VR_MODE); - break; - case POWER_HINT_INTERACTION: - ret_val = process_interaction_hint(data); - break; - case POWER_HINT_LAUNCH: - ret_val = process_activity_launch_hint(data); - break; - default: - break; - } - return ret_val; -} - -int set_interactive_override(struct power_module* module, int on) { - static int set_i_count = 0; - - set_i_count++; - ALOGI("Got set_interactive hint on= %d, count= %d\n", on, set_i_count); - - return HINT_HANDLED; /* Don't excecute this code path, not in use */ -} diff --git a/power/power-common.c b/power/power-common.c new file mode 100644 index 0000000..0101bea --- /dev/null +++ b/power/power-common.c @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2012-2019, 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 +#include + +#define LOG_TAG "QTI PowerHAL" +#include +#include +#include + +#include "utils.h" +#include "hint-data.h" +#include "performance.h" +#include "power-common.h" + +static struct hint_handles handles[NUM_HINTS]; + +void power_init() +{ + ALOGI("Initing"); + + for (int i=0; i 0) + handles[hint].ref_count++; + } + else + if (handles[hint].handle > 0) + if (--handles[hint].ref_count == 0) { + release_request(handles[hint].handle); + handles[hint].handle = 0; + } + else + ALOGE("Lock for hint: %X was not acquired, cannot be released", hint); + break; + } +} + +int __attribute__ ((weak)) set_interactive_override(int on) +{ + return HINT_NONE; +} + +void set_interactive(int on) +{ + if (!on) { + /* Send Display OFF hint to perf HAL */ + perf_hint_enable(VENDOR_HINT_DISPLAY_OFF, 0); + } else { + /* Send Display ON hint to perf HAL */ + perf_hint_enable(VENDOR_HINT_DISPLAY_ON, 0); + } + + if (set_interactive_override(on) == HINT_HANDLED) { + return; + } + + ALOGI("Got set_interactive hint"); +} diff --git a/power/power-common.h b/power/power-common.h index f3d70d3..697302a 100644 --- a/power/power-common.h +++ b/power/power-common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, The Linux Foundation. All rights reserved. + * Copyright (c) 2013, 2018-2019 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 @@ -26,6 +26,13 @@ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#ifndef __POWER_COMMON_H__ +#define __POWER_COMMON_H__ + +#ifdef __cplusplus +extern "C" { +#endif + #define NODE_MAX (64) #define SCALING_GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" @@ -37,8 +44,26 @@ #define ONDEMAND_GOVERNOR "ondemand" #define INTERACTIVE_GOVERNOR "interactive" #define MSMDCVS_GOVERNOR "msm-dcvs" +#define SCHEDUTIL_GOVERNOR "schedutil" #define HINT_HANDLED (0) #define HINT_NONE (-1) -enum CPU_GOV_CHECK { CPU0 = 0, CPU1 = 1, CPU2 = 2, CPU3 = 3 }; +#include + +enum CPU_GOV_CHECK { + CPU0 = 0, + CPU1 = 1, + CPU2 = 2, + CPU3 = 3 +}; + +void power_init(void); +void power_hint(power_hint_t hint, void *data); +void set_interactive(int on); + +#ifdef __cplusplus +} +#endif + +#endif //__POWER_COMMON_H___ diff --git a/power/power.c b/power/power.c deleted file mode 100644 index 8cf2e59..0000000 --- a/power/power.c +++ /dev/null @@ -1,506 +0,0 @@ -/* - * Copyright (c) 2012-2017, 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 "QCOM PowerHAL" -#include -#include -#include - -#include "hint-data.h" -#include "metadata-defs.h" -#include "performance.h" -#include "power-common.h" -#include "utils.h" - -static int saved_dcvs_cpu0_slack_max = -1; -static int saved_dcvs_cpu0_slack_min = -1; -static int saved_mpdecision_slack_max = -1; -static int saved_mpdecision_slack_min = -1; -static int saved_interactive_mode = -1; -static int slack_node_rw_failed = 0; -static int display_hint_sent; -int display_boost; - -static int power_device_open(const hw_module_t* module, const char* name, hw_device_t** device); - -static struct hw_module_methods_t power_module_methods = { - .open = power_device_open, -}; - -static void power_init(struct power_module* module) { - ALOGI("QCOM power HAL initing."); - - int fd; - char buf[10] = {0}; - - fd = open("/sys/devices/soc0/soc_id", O_RDONLY); - if (fd >= 0) { - if (read(fd, buf, sizeof(buf) - 1) == -1) { - ALOGW("Unable to read soc_id"); - } else { - int soc_id = atoi(buf); - if (soc_id == 194 || (soc_id >= 208 && soc_id <= 218) || soc_id == 178) { - display_boost = 1; - } - } - close(fd); - } -} - -static void process_video_decode_hint(void* metadata) { - char governor[80]; - struct video_decode_metadata_t video_decode_metadata; - - if (get_scaling_governor(governor, sizeof(governor)) == -1) { - ALOGE("Can't obtain scaling governor."); - - return; - } - - if (metadata) { - ALOGI("Processing video decode hint. Metadata: %s", (char*)metadata); - } - - /* Initialize encode metadata struct fields. */ - memset(&video_decode_metadata, 0, sizeof(struct video_decode_metadata_t)); - video_decode_metadata.state = -1; - video_decode_metadata.hint_id = DEFAULT_VIDEO_DECODE_HINT_ID; - - if (metadata) { - if (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { - ALOGE("Error occurred while parsing metadata."); - return; - } - } else { - return; - } - - if (video_decode_metadata.state == 1) { - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - int resource_values[] = {THREAD_MIGRATION_SYNC_OFF}; - - perform_hint_action(video_decode_metadata.hint_id, resource_values, - sizeof(resource_values) / sizeof(resource_values[0])); - } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - int resource_values[] = {TR_MS_30, HISPEED_LOAD_90, HS_FREQ_1026, - THREAD_MIGRATION_SYNC_OFF}; - - perform_hint_action(video_decode_metadata.hint_id, resource_values, - sizeof(resource_values) / sizeof(resource_values[0])); - } - } else if (video_decode_metadata.state == 0) { - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - undo_hint_action(video_decode_metadata.hint_id); - } - } -} - -static void process_video_encode_hint(void* metadata) { - char governor[80]; - struct video_encode_metadata_t video_encode_metadata; - - if (get_scaling_governor(governor, sizeof(governor)) == -1) { - ALOGE("Can't obtain scaling governor."); - - return; - } - - /* 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, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - int resource_values[] = {IO_BUSY_OFF, SAMPLING_DOWN_FACTOR_1, THREAD_MIGRATION_SYNC_OFF}; - - perform_hint_action(video_encode_metadata.hint_id, resource_values, - sizeof(resource_values) / sizeof(resource_values[0])); - } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - int resource_values[] = {TR_MS_30, HISPEED_LOAD_90, HS_FREQ_1026, - THREAD_MIGRATION_SYNC_OFF, INTERACTIVE_IO_BUSY_OFF}; - - perform_hint_action(video_encode_metadata.hint_id, resource_values, - sizeof(resource_values) / sizeof(resource_values[0])); - } - } else if (video_encode_metadata.state == 0) { - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - undo_hint_action(video_encode_metadata.hint_id); - } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - undo_hint_action(video_encode_metadata.hint_id); - } - } -} - -int __attribute__((weak)) -power_hint_override(struct power_module* module, power_hint_t hint, void* data) { - return HINT_NONE; -} - -/* Declare function before use */ -void interaction(int duration, int num_args, int opt_list[]); - -static void power_hint(struct power_module* module, power_hint_t hint, void* data) { - /* Check if this hint has been overridden. */ - if (power_hint_override(module, hint, data) == HINT_HANDLED) { - /* The power_hint has been handled. We can skip the rest. */ - return; - } - - switch (hint) { - case POWER_HINT_VSYNC: - break; - case POWER_HINT_SUSTAINED_PERFORMANCE: - ALOGI("Sustained perf power hint not handled in power_hint_override"); - break; - case POWER_HINT_VR_MODE: - ALOGI("VR mode power hint not handled in power_hint_override"); - break; - case POWER_HINT_INTERACTION: { - int resources[] = {0x702, 0x20F, 0x30F}; - int duration = 3000; - - interaction(duration, sizeof(resources) / sizeof(resources[0]), resources); - } break; - case POWER_HINT_VIDEO_ENCODE: - process_video_encode_hint(data); - break; - case POWER_HINT_VIDEO_DECODE: - process_video_decode_hint(data); - break; - default: - break; - } -} - -int __attribute__((weak)) set_interactive_override(struct power_module* module, int on) { - return HINT_NONE; -} - -void set_interactive(struct power_module* module, int on) { - char governor[80]; - char tmp_str[NODE_MAX]; - int rc = 0; - - if (!on) { - /* Send Display OFF hint to perf HAL */ - perf_hint_enable(VENDOR_HINT_DISPLAY_OFF, 0); - } else { - /* Send Display ON hint to perf HAL */ - perf_hint_enable(VENDOR_HINT_DISPLAY_ON, 0); - } - - if (set_interactive_override(module, on) == HINT_HANDLED) { - return; - } - - ALOGI("Got set_interactive hint"); - - if (get_scaling_governor(governor, sizeof(governor)) == -1) { - ALOGE("Can't obtain scaling governor."); - - return; - } - - if (!on) { - /* Display off. */ - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - int resource_values[] = {DISPLAY_OFF, 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; - } - } else if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - int resource_values[] = {TR_MS_50, 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; - } - } else if ((strncmp(governor, MSMDCVS_GOVERNOR, strlen(MSMDCVS_GOVERNOR)) == 0) && - (strlen(governor) == strlen(MSMDCVS_GOVERNOR))) { - if (saved_interactive_mode == 1) { - /* Display turned off. */ - if (sysfs_read(DCVS_CPU0_SLACK_MAX_NODE, tmp_str, NODE_MAX - 1)) { - if (!slack_node_rw_failed) { - ALOGE("Failed to read from %s", DCVS_CPU0_SLACK_MAX_NODE); - } - - rc = 1; - } else { - saved_dcvs_cpu0_slack_max = atoi(tmp_str); - } - - if (sysfs_read(DCVS_CPU0_SLACK_MIN_NODE, tmp_str, NODE_MAX - 1)) { - if (!slack_node_rw_failed) { - ALOGE("Failed to read from %s", DCVS_CPU0_SLACK_MIN_NODE); - } - - rc = 1; - } else { - saved_dcvs_cpu0_slack_min = atoi(tmp_str); - } - - if (sysfs_read(MPDECISION_SLACK_MAX_NODE, tmp_str, NODE_MAX - 1)) { - if (!slack_node_rw_failed) { - ALOGE("Failed to read from %s", MPDECISION_SLACK_MAX_NODE); - } - - rc = 1; - } else { - saved_mpdecision_slack_max = atoi(tmp_str); - } - - if (sysfs_read(MPDECISION_SLACK_MIN_NODE, tmp_str, NODE_MAX - 1)) { - if (!slack_node_rw_failed) { - ALOGE("Failed to read from %s", MPDECISION_SLACK_MIN_NODE); - } - - rc = 1; - } else { - saved_mpdecision_slack_min = atoi(tmp_str); - } - - /* Write new values. */ - if (saved_dcvs_cpu0_slack_max != -1) { - snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_dcvs_cpu0_slack_max); - - if (sysfs_write(DCVS_CPU0_SLACK_MAX_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MAX_NODE); - } - - rc = 1; - } - } - - if (saved_dcvs_cpu0_slack_min != -1) { - snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_dcvs_cpu0_slack_min); - - if (sysfs_write(DCVS_CPU0_SLACK_MIN_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MIN_NODE); - } - - rc = 1; - } - } - - if (saved_mpdecision_slack_max != -1) { - snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_mpdecision_slack_max); - - if (sysfs_write(MPDECISION_SLACK_MAX_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", MPDECISION_SLACK_MAX_NODE); - } - - rc = 1; - } - } - - if (saved_mpdecision_slack_min != -1) { - snprintf(tmp_str, NODE_MAX, "%d", 10 * saved_mpdecision_slack_min); - - if (sysfs_write(MPDECISION_SLACK_MIN_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", MPDECISION_SLACK_MIN_NODE); - } - - rc = 1; - } - } - } - - slack_node_rw_failed = rc; - } - } 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; - } else 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; - } else if ((strncmp(governor, MSMDCVS_GOVERNOR, strlen(MSMDCVS_GOVERNOR)) == 0) && - (strlen(governor) == strlen(MSMDCVS_GOVERNOR))) { - if (saved_interactive_mode == -1 || saved_interactive_mode == 0) { - /* Display turned on. Restore if possible. */ - if (saved_dcvs_cpu0_slack_max != -1) { - snprintf(tmp_str, NODE_MAX, "%d", saved_dcvs_cpu0_slack_max); - - if (sysfs_write(DCVS_CPU0_SLACK_MAX_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MAX_NODE); - } - - rc = 1; - } - } - - if (saved_dcvs_cpu0_slack_min != -1) { - snprintf(tmp_str, NODE_MAX, "%d", saved_dcvs_cpu0_slack_min); - - if (sysfs_write(DCVS_CPU0_SLACK_MIN_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", DCVS_CPU0_SLACK_MIN_NODE); - } - - rc = 1; - } - } - - if (saved_mpdecision_slack_max != -1) { - snprintf(tmp_str, NODE_MAX, "%d", saved_mpdecision_slack_max); - - if (sysfs_write(MPDECISION_SLACK_MAX_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", MPDECISION_SLACK_MAX_NODE); - } - - rc = 1; - } - } - - if (saved_mpdecision_slack_min != -1) { - snprintf(tmp_str, NODE_MAX, "%d", saved_mpdecision_slack_min); - - if (sysfs_write(MPDECISION_SLACK_MIN_NODE, tmp_str) != 0) { - if (!slack_node_rw_failed) { - ALOGE("Failed to write to %s", MPDECISION_SLACK_MIN_NODE); - } - - rc = 1; - } - } - } - - slack_node_rw_failed = rc; - } - } - - saved_interactive_mode = !!on; -} - -void set_feature(struct power_module* module, feature_t feature, int state) { - switch (feature) { - case POWER_FEATURE_DOUBLE_TAP_TO_WAKE: - sysfs_write("/proc/touchpanel/double_tap_enable", state ? "1" : "0"); - break; - default: - break; - } -} - -static int power_device_open(const hw_module_t* module, const char* name, hw_device_t** device) { - int status = -EINVAL; - if (module && name && device) { - if (!strcmp(name, POWER_HARDWARE_MODULE_ID)) { - power_module_t* dev = (power_module_t*)malloc(sizeof(*dev)); - - if (dev) { - memset(dev, 0, sizeof(*dev)); - - if (dev) { - /* initialize the fields */ - dev->common.module_api_version = POWER_MODULE_API_VERSION_0_3; - dev->common.tag = HARDWARE_DEVICE_TAG; - dev->init = power_init; - dev->powerHint = power_hint; - dev->setInteractive = set_interactive; - dev->setFeature = set_feature; - /* At the moment we support 0.3 APIs */ - dev->get_number_of_platform_modes = NULL; - dev->get_platform_low_power_stats = NULL; - dev->get_voter_list = NULL; - *device = (hw_device_t*)dev; - status = 0; - } else { - status = -ENOMEM; - } - } else { - status = -ENOMEM; - } - } - } - - return status; -} - -struct power_module HAL_MODULE_INFO_SYM = { - .common = - { - .tag = HARDWARE_MODULE_TAG, - .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", - .author = "Qualcomm", - .methods = &power_module_methods, - }, - - .init = power_init, - .powerHint = power_hint, - .setInteractive = set_interactive, - .setFeature = set_feature, -}; diff --git a/power/powerhintparser.c b/power/powerhintparser.c index 648a219..6d8646f 100644 --- a/power/powerhintparser.c +++ b/power/powerhintparser.c @@ -26,18 +26,18 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * */ - -#define LOG_TAG "QCOM PowerHAL" - -#include "powerhintparser.h" #include -#include #include +#include +#include #include #include -#include +#include +#include "powerhintparser.h" +#define LOG_TAG "QTI PowerHAL" int parsePowerhintXML() { + xmlDocPtr doc; xmlNodePtr currNode; const char *opcode_str, *value_str, *type_str; @@ -45,18 +45,18 @@ int parsePowerhintXML() { int numParams = 0; static int hintCount; - if (access(POWERHINT_XML, F_OK) < 0) { + if(access(POWERHINT_XML, F_OK) < 0) { return -1; } doc = xmlReadFile(POWERHINT_XML, "UTF-8", XML_PARSE_RECOVER); - if (!doc) { + if(!doc) { ALOGE("Document not parsed successfully"); return -1; } currNode = xmlDocGetRootElement(doc); - if (!currNode) { + if(!currNode) { ALOGE("Empty document"); xmlFreeDoc(doc); xmlCleanupParser(); @@ -64,7 +64,7 @@ int parsePowerhintXML() { } // Confirm the root-element of the tree - if (xmlStrcmp(currNode->name, BAD_CAST "Powerhint")) { + if(xmlStrcmp(currNode->name, BAD_CAST "Powerhint")) { ALOGE("document of the wrong type, root node != root"); xmlFreeDoc(doc); xmlCleanupParser(); @@ -73,34 +73,39 @@ int parsePowerhintXML() { currNode = currNode->xmlChildrenNode; - for (; currNode != NULL; currNode = currNode->next) { - if (currNode->type != XML_ELEMENT_NODE) continue; + for(; currNode != NULL; currNode=currNode->next) { + + if(currNode->type != XML_ELEMENT_NODE) + continue; xmlNodePtr node = currNode; - if (hintCount == MAX_HINT) { - ALOGE("Number of hints exceeded the max count of %d\n", MAX_HINT); + if(hintCount == MAX_HINT) { + ALOGE("Number of hints exceeded the max count of %d\n",MAX_HINT); break; } - if (!xmlStrcmp(node->name, BAD_CAST "Hint")) { - if (xmlHasProp(node, BAD_CAST "type")) { - type_str = (const char*)xmlGetProp(node, BAD_CAST "type"); - if (type_str == NULL) { - ALOGE("xmlGetProp failed on type"); - xmlFreeDoc(doc); - xmlCleanupParser(); - return -1; - } - type = strtol(type_str, NULL, 16); + if(!xmlStrcmp(node->name, BAD_CAST "Hint")) { + if(xmlHasProp(node, BAD_CAST "type")) { + type_str = (const char*)xmlGetProp(node, BAD_CAST "type"); + if (type_str == NULL) + { + ALOGE("xmlGetProp failed on type"); + xmlFreeDoc(doc); + xmlCleanupParser(); + return -1; + } + type = strtol(type_str, NULL, 16); } node = node->children; - while (node != NULL) { - if (!xmlStrcmp(node->name, BAD_CAST "Resource")) { - if (xmlHasProp(node, BAD_CAST "opcode")) { - opcode_str = (const char*)xmlGetProp(node, BAD_CAST "opcode"); - if (opcode_str == NULL) { + while(node != NULL) { + if(!xmlStrcmp(node->name, BAD_CAST "Resource")) { + + if(xmlHasProp(node, BAD_CAST "opcode")) { + opcode_str = (const char*)xmlGetProp(node, BAD_CAST "opcode"); + if (opcode_str == NULL) + { ALOGE("xmlGetProp failed on opcode"); xmlFreeDoc(doc); xmlCleanupParser(); @@ -108,9 +113,10 @@ int parsePowerhintXML() { } opcode = strtol(opcode_str, NULL, 16); } - if (xmlHasProp(node, BAD_CAST "value")) { + if(xmlHasProp(node, BAD_CAST "value")) { value_str = (const char*)xmlGetProp(node, BAD_CAST "value"); - if (value_str == NULL) { + if (value_str == NULL) + { ALOGE("xmlGetProp failed on value"); xmlFreeDoc(doc); xmlCleanupParser(); @@ -118,12 +124,12 @@ int parsePowerhintXML() { } value = strtol(value_str, NULL, 16); } - if (opcode > 0) { - if (numParams < (MAX_PARAM - 1)) { + if(opcode > 0) { + if(numParams < (MAX_PARAM-1)) { powerhint[hintCount].paramList[numParams++] = opcode; powerhint[hintCount].paramList[numParams++] = value; } else { - ALOGE("Maximum parameters exceeded for Hint ID %x\n", type); + ALOGE("Maximum parameters exceeded for Hint ID %x\n",type); opcode = value = 0; break; } @@ -145,27 +151,29 @@ int parsePowerhintXML() { return 0; } -int* getPowerhint(int hint_id, int* params) { - int* result = NULL; +int* getPowerhint(int hint_id, int *params) { - if (!hint_id) return result; + int *result = NULL; - ALOGI("Powerhal hint received=%x\n", hint_id); + if(!hint_id) + return result; - if (!powerhint[0].numParams) { - parsePowerhintXML(); + ALOGI("Powerhal hint received=%x\n",hint_id); + + if(!powerhint[0].numParams) { + parsePowerhintXML(); } - for (int i = 0; i < MAX_HINT; i++) { - if (hint_id == powerhint[i].type) { - *params = powerhint[i].numParams; - result = powerhint[i].paramList; - break; - } + for(int i = 0; i < MAX_HINT; i++) { + if(hint_id == powerhint[i].type) { + *params = powerhint[i].numParams; + result = powerhint[i].paramList; + break; + } } /*for (int j = 0; j < *params; j++) ALOGI("Powerhal resource again%x = \n", result[j]);*/ - return result; + return result; } diff --git a/power/powerhintparser.h b/power/powerhintparser.h index 48a9bb4..5f9cbe6 100644 --- a/power/powerhintparser.h +++ b/power/powerhintparser.h @@ -30,19 +30,19 @@ #ifndef __POWERHINTPARSER__ #define __POWERHINTPARSER__ -#define POWERHINT_XML "/vendor/etc/powerhint.xml" +#define POWERHINT_XML "/vendor/etc/powerhint.xml" #define MAX_HINT 6 #define MAX_PARAM 30 typedef struct perflock_param_t { int type; int numParams; - int paramList[MAX_PARAM]; // static limit on number of hints - 15 -} perflock_param_t; + int paramList[MAX_PARAM];//static limit on number of hints - 15 +}perflock_param_t; static perflock_param_t powerhint[MAX_HINT]; int parsePowerhintXML(); -int* getPowerhint(int, int*); +int *getPowerhint(int, int*); #endif /* __POWERHINTPARSER__ */ diff --git a/power/service.cpp b/power/service.cpp new file mode 100644 index 0000000..902c661 --- /dev/null +++ b/power/service.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2019, 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_TAG "android.hardware.power@1.2-service" + +#include +#include +#include +#include "Power.h" + +using android::sp; +using android::status_t; +using android::OK; + +// libhwbinder: +using android::hardware::configureRpcThreadpool; +using android::hardware::joinRpcThreadpool; + +// Generated HIDL files +using android::hardware::power::V1_2::IPower; +using android::hardware::power::V1_2::implementation::Power; + +int main() { + + status_t status; + android::sp service = nullptr; + + ALOGI("Power HAL Service 1.2 is starting."); + + service = new Power(); + if (service == nullptr) { + ALOGE("Can not create an instance of Power HAL interface."); + + goto shutdown; + } + + configureRpcThreadpool(1, true /*callerWillJoin*/); + + status = service->registerAsService(); + if (status != OK) { + ALOGE("Could not register service for Power HAL(%d).", status); + goto shutdown; + } + + ALOGI("Power Service is ready"); + joinRpcThreadpool(); + //Should not pass this line + +shutdown: + // In normal operation, we don't expect the thread pool to exit + + ALOGE("Power Service is shutting down"); + return 1; +} + diff --git a/power/utils.c b/power/utils.c index 030f56e..f7f2251 100644 --- a/power/utils.c +++ b/power/utils.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012-2013,2015-2017, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2013,2015-2018, 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 @@ -29,48 +29,53 @@ #define LOG_NIDEBUG 0 #include -#include #include +#include #include #include +#include -#include "hint-data.h" -#include "list.h" -#include "power-common.h" #include "utils.h" +#include "list.h" +#include "hint-data.h" +#include "power-common.h" -#define LOG_TAG "QCOM PowerHAL" +#define LOG_TAG "QTI PowerHAL" #include -#define USINSEC 1000000L -#define NSINUS 1000L - -char scaling_gov_path[4][80] = {"sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", - "sys/devices/system/cpu/cpu1/cpufreq/scaling_governor", - "sys/devices/system/cpu/cpu2/cpufreq/scaling_governor", - "sys/devices/system/cpu/cpu3/cpufreq/scaling_governor"}; +char scaling_gov_path[4][80] ={ + "sys/devices/system/cpu/cpu0/cpufreq/scaling_governor", + "sys/devices/system/cpu/cpu1/cpufreq/scaling_governor", + "sys/devices/system/cpu/cpu2/cpufreq/scaling_governor", + "sys/devices/system/cpu/cpu3/cpufreq/scaling_governor" +}; #define PERF_HAL_PATH "libqti-perfd-client.so" -static void* qcopt_handle; -static int (*perf_lock_acq)(unsigned long handle, int duration, int list[], int numArgs); -static int (*perf_lock_rel)(unsigned long handle); -static int (*perf_hint)(int, char*, int, int); +static void *qcopt_handle; +static int (*perf_lock_acq)(int handle, int duration, + int list[], int numArgs); +static int (*perf_lock_rel)(int handle); +static int (*perf_hint)(int, const char *, int, int); static struct list_node active_hint_list_head; +const char *pkg = "QTI PowerHAL"; -static void* get_qcopt_handle() { - void* handle = NULL; +static void *get_qcopt_handle() +{ + void *handle = NULL; dlerror(); handle = dlopen(PERF_HAL_PATH, RTLD_NOW); if (!handle) { - ALOGE("Unable to open %s: %s\n", PERF_HAL_PATH, dlerror()); + ALOGE("Unable to open %s: %s\n", PERF_HAL_PATH, + dlerror()); } return handle; } -static void __attribute__((constructor)) initialize(void) { +static void __attribute__ ((constructor)) initialize(void) +{ qcopt_handle = get_qcopt_handle(); if (!qcopt_handle) { @@ -100,13 +105,16 @@ static void __attribute__((constructor)) initialize(void) { } } -static void __attribute__((destructor)) cleanup(void) { +static void __attribute__ ((destructor)) cleanup(void) +{ if (qcopt_handle) { - if (dlclose(qcopt_handle)) ALOGE("Error occurred while closing qc-opt library."); + if (dlclose(qcopt_handle)) + ALOGE("Error occurred while closing qc-opt library."); } } -int sysfs_read(char* path, char* s, int num_bytes) { +int sysfs_read(char *path, char *s, int num_bytes) +{ char buf[80]; int count; int ret = 0; @@ -133,7 +141,8 @@ int sysfs_read(char* path, char* s, int num_bytes) { return ret; } -int sysfs_write(char* path, char* s) { +int sysfs_write(char *path, char *s) +{ char buf[80]; int len; int ret = 0; @@ -142,7 +151,7 @@ int sysfs_write(char* path, char* s) { if (fd < 0) { strerror_r(errno, buf, sizeof(buf)); ALOGE("Error opening %s: %s\n", path, buf); - return -1; + return -1 ; } len = write(fd, s, strlen(s)); @@ -158,8 +167,10 @@ int sysfs_write(char* path, char* s) { return ret; } -int get_scaling_governor(char governor[], int size) { - if (sysfs_read(SCALING_GOVERNOR_PATH, governor, size) == -1) { +int get_scaling_governor(char governor[], int size) +{ + if (sysfs_read(SCALING_GOVERNOR_PATH, governor, + size) == -1) { // Can't obtain the scaling governor. Return. return -1; } else { @@ -168,14 +179,18 @@ int get_scaling_governor(char governor[], int size) { len--; - while (len >= 0 && (governor[len] == '\n' || governor[len] == '\r')) governor[len--] = '\0'; + while (len >= 0 && (governor[len] == '\n' || governor[len] == '\r')) + governor[len--] = '\0'; } return 0; } -int get_scaling_governor_check_cores(char governor[], int size, int core_num) { - if (sysfs_read(scaling_gov_path[core_num], governor, size) == -1) { +int get_scaling_governor_check_cores(char governor[], int size,int core_num) +{ + + if (sysfs_read(scaling_gov_path[core_num], governor, + size) == -1) { // Can't obtain the scaling governor. Return. return -1; } @@ -183,92 +198,96 @@ int get_scaling_governor_check_cores(char governor[], int size, int core_num) { // Strip newline at the end. int len = strlen(governor); len--; - while (len >= 0 && (governor[len] == '\n' || governor[len] == '\r')) governor[len--] = '\0'; + while (len >= 0 && (governor[len] == '\n' || governor[len] == '\r')) + governor[len--] = '\0'; return 0; } int is_interactive_governor(char* governor) { - if (strncmp(governor, INTERACTIVE_GOVERNOR, (strlen(INTERACTIVE_GOVERNOR) + 1)) == 0) return 1; - return 0; + if (strncmp(governor, INTERACTIVE_GOVERNOR, (strlen(INTERACTIVE_GOVERNOR)+1)) == 0) + return 1; + return 0; } -void interaction(int duration, int num_args, int opt_list[]) { +void interaction(int duration, int num_args, int opt_list[]) +{ #ifdef INTERACTION_BOOST static int lock_handle = 0; - if (duration < 0 || num_args < 1 || opt_list[0] == 0) return; + if (duration < 0 || num_args < 1 || opt_list[0] == NULL) + return; if (qcopt_handle) { if (perf_lock_acq) { lock_handle = perf_lock_acq(lock_handle, duration, opt_list, num_args); - if (lock_handle == -1) ALOGE("Failed to acquire lock."); + if (lock_handle == -1) + ALOGE("Failed to acquire lock."); } } #endif } -int interaction_with_handle(int lock_handle, int duration, int num_args, int opt_list[]) { - if (duration < 0 || num_args < 1 || opt_list[0] == 0) return 0; +int interaction_with_handle(int lock_handle, int duration, int num_args, int opt_list[]) +{ + if (duration < 0 || num_args < 1 || opt_list[0] == NULL) + return 0; if (qcopt_handle) { if (perf_lock_acq) { lock_handle = perf_lock_acq(lock_handle, duration, opt_list, num_args); - if (lock_handle == -1) ALOGE("Failed to acquire lock."); + if (lock_handle == -1) + ALOGE("Failed to acquire lock."); } } return lock_handle; } -// this is interaction_with_handle using perf_hint instead of -// perf_lock_acq -int perf_hint_enable(int hint_id, int duration) { +//this is interaction_with_handle using perf_hint instead of +//perf_lock_acq +int perf_hint_enable(int hint_id , int duration) +{ int lock_handle = 0; - if (duration < 0) return 0; + if (duration < 0) + return 0; if (qcopt_handle) { if (perf_hint) { - lock_handle = perf_hint(hint_id, NULL, duration, -1); - if (lock_handle == -1) ALOGE("Failed to acquire lock."); + lock_handle = perf_hint(hint_id, pkg, duration, -1); + if (lock_handle == -1) + ALOGE("Failed to acquire lock for hint_id: %X.", hint_id); } } return lock_handle; } -// same as perf_hint_enable, but with the ability to choose the type -int perf_hint_enable_with_type(int hint_id, int duration, int type) { - int lock_handle = 0; - - if (qcopt_handle) { - if (perf_hint) { - lock_handle = perf_hint(hint_id, NULL, duration, type); - if (lock_handle == -1) ALOGE("Failed to acquire lock."); - } - } - return lock_handle; -} void release_request(int lock_handle) { - if (qcopt_handle && perf_lock_rel) perf_lock_rel(lock_handle); + if (qcopt_handle && perf_lock_rel) + perf_lock_rel(lock_handle); } -void perform_hint_action(int hint_id, int resource_values[], int num_resources) { +void perform_hint_action(int hint_id, int resource_values[], int num_resources) +{ if (qcopt_handle) { if (perf_lock_acq) { /* Acquire an indefinite lock for the requested resources. */ - int lock_handle = perf_lock_acq(0, 0, resource_values, num_resources); + int lock_handle = perf_lock_acq(0, 0, resource_values, + num_resources); if (lock_handle == -1) { ALOGE("Failed to acquire lock."); } else { /* Add this handle to our internal hint-list. */ - struct hint_data* new_hint = (struct hint_data*)malloc(sizeof(struct hint_data)); + struct hint_data *new_hint = + (struct hint_data *)malloc(sizeof(struct hint_data)); if (new_hint) { if (!active_hint_list_head.compare) { - active_hint_list_head.compare = (int (*)(void*, void*))hint_compare; - active_hint_list_head.dump = (void (*)(void*))hint_dump; + active_hint_list_head.compare = + (int (*)(void *, void *))hint_compare; + active_hint_list_head.dump = (void (*)(void *))hint_dump; } new_hint->hint_id = hint_id; @@ -277,13 +296,15 @@ void perform_hint_action(int hint_id, int resource_values[], int num_resources) if (add_list_node(&active_hint_list_head, new_hint) == NULL) { free(new_hint); /* Can't keep track of this lock. Release it. */ - if (perf_lock_rel) perf_lock_rel(lock_handle); + if (perf_lock_rel) + perf_lock_rel(lock_handle); ALOGE("Failed to process hint."); } } else { /* Can't keep track of this lock. Release it. */ - if (perf_lock_rel) perf_lock_rel(lock_handle); + if (perf_lock_rel) + perf_lock_rel(lock_handle); ALOGE("Failed to process hint."); } @@ -292,18 +313,23 @@ void perform_hint_action(int hint_id, int resource_values[], int num_resources) } } -void undo_hint_action(int hint_id) { +void undo_hint_action(int hint_id) +{ if (qcopt_handle) { if (perf_lock_rel) { /* Get hint-data associated with this hint-id */ - struct list_node* found_node; - struct hint_data temp_hint_data = {.hint_id = hint_id}; + struct list_node *found_node; + struct hint_data temp_hint_data = { + .hint_id = hint_id + }; - found_node = find_node(&active_hint_list_head, &temp_hint_data); + found_node = find_node(&active_hint_list_head, + &temp_hint_data); if (found_node) { /* Release this lock. */ - struct hint_data* found_hint_data = (struct hint_data*)(found_node->data); + struct hint_data *found_hint_data = + (struct hint_data *)(found_node->data); if (found_hint_data) { if (perf_lock_rel(found_hint_data->perflock_handle) == -1) @@ -327,17 +353,11 @@ void undo_hint_action(int hint_id) { * Used to release initial lock holding * two cores online when the display is on */ -void undo_initial_hint_action() { +void undo_initial_hint_action() +{ if (qcopt_handle) { if (perf_lock_rel) { perf_lock_rel(1); } } } - -long long calc_timespan_us(struct timespec start, struct timespec end) { - long long diff_in_us = 0; - diff_in_us += (end.tv_sec - start.tv_sec) * USINSEC; - diff_in_us += (end.tv_nsec - start.tv_nsec) / NSINUS; - return diff_in_us; -} diff --git a/power/utils.h b/power/utils.h index 770f843..4c3dc7f 100644 --- a/power/utils.h +++ b/power/utils.h @@ -29,21 +29,19 @@ #include -int sysfs_read(char* path, char* s, int num_bytes); -int sysfs_write(char* path, char* s); +int sysfs_read(char *path, char *s, int num_bytes); +int sysfs_write(char *path, char *s); int get_scaling_governor(char governor[], int size); -int get_scaling_governor_check_cores(char governor[], int size, int core_num); +int get_scaling_governor_check_cores(char governor[], int size,int core_num); int is_interactive_governor(char*); void vote_ondemand_io_busy_off(); void unvote_ondemand_io_busy_off(); void vote_ondemand_sdf_low(); void unvote_ondemand_sdf_low(); -void perform_hint_action(int hint_id, int resource_values[], int num_resources); +void perform_hint_action(int hint_id, int resource_values[], + int num_resources); void undo_hint_action(int hint_id); void release_request(int lock_handle); int interaction_with_handle(int lock_handle, int duration, int num_args, int opt_list[]); int perf_hint_enable(int hint_id, int duration); -int perf_hint_enable_with_type(int hint_id, int duration, int type); - -long long calc_timespan_us(struct timespec start, struct timespec end); diff --git a/sepolicy/private/file_contexts b/sepolicy/private/file_contexts index 7e1c6ac..50f205e 100644 --- a/sepolicy/private/file_contexts +++ b/sepolicy/private/file_contexts @@ -11,6 +11,7 @@ # HALs /(product|system/product)/vendor_overlay/[0-9]+/bin/hw/android\.hardware\.light@2\.0-service u:object_r:hal_light_default_exec:s0 +/(product|system/product)/vendor_overlay/[0-9]+/bin/hw/android\.hardware\.power@1\.2-service u:object_r:hal_power_default_exec:s0 /system/bin/hw/lineage\.biometrics\.fingerprint\.inscreen@1.0-service\.oneplus_kona u:object_r:hal_fod_kona_exec:s0 /system/bin/hw/lineage\.livedisplay@2\.0-service\.oneplus_kona u:object_r:hal_livedisplay_kona_exec:s0 /system/bin/hw/lineage\.touch@1\.0-service\.oneplus_kona u:object_r:hal_touch_kona_exec:s0