diff --git a/.clang-format b/.clang-format new file mode 120000 index 0000000..0457b53 --- /dev/null +++ b/.clang-format @@ -0,0 +1 @@ +../../../../build/soong/scripts/system-clang-format \ No newline at end of file diff --git a/Android.mk b/Android.mk index 971dafb..bd5a4ac 100644 --- a/Android.mk +++ b/Android.mk @@ -2,28 +2,51 @@ LOCAL_PATH := $(call my-dir) ifeq ($(call is-vendor-board-platform,QCOM),true) -# HAL module implemenation stored in -# hw/..so include $(CLEAR_VARS) LOCAL_MODULE_RELATIVE_PATH := hw -LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libxml2 libbase libutils android.hardware.power-ndk_platform libbinder_ndk -LOCAL_HEADER_LIBRARIES += libutils_headers -LOCAL_HEADER_LIBRARIES += libhardware_headers -LOCAL_SRC_FILES := power-common.c metadata-parser.c utils.c list.c hint-data.c powerhintparser.c Power.cpp main.cpp -LOCAL_C_INCLUDES := external/libxml2/include \ - external/icu/icu4c/source/common + +LOCAL_SHARED_LIBRARIES := \ + liblog \ + libcutils \ + libdl \ + libbase \ + libutils \ + android.hardware.power-ndk_platform \ + libbinder_ndk + +LOCAL_HEADER_LIBRARIES := \ + libhardware_headers + +LOCAL_SRC_FILES := \ + power-common.c \ + metadata-parser.c \ + utils.c \ + list.c \ + hint-data.c \ + Power.cpp \ + main.cpp + +LOCAL_CFLAGS += -Wall -Wextra -Werror + +ifneq ($(BOARD_POWER_CUSTOM_BOARD_LIB),) + LOCAL_WHOLE_STATIC_LIBRARIES += $(BOARD_POWER_CUSTOM_BOARD_LIB) +else # Include target-specific files. -ifeq ($(call is-board-platform-in-list, msm8974), true) +ifeq ($(call is-board-platform-in-list,msm8960), true) +LOCAL_SRC_FILES += power-8960.c +endif + +ifeq ($(call is-board-platform-in-list,msm8974), true) LOCAL_SRC_FILES += power-8974.c endif -ifeq ($(call is-board-platform-in-list, msm8226), true) +ifeq ($(call is-board-platform-in-list,msm8226), true) LOCAL_SRC_FILES += power-8226.c endif -ifeq ($(call is-board-platform-in-list, msm8610), true) +ifeq ($(call is-board-platform-in-list,msm8610), true) LOCAL_SRC_FILES += power-8610.c endif @@ -31,16 +54,28 @@ ifeq ($(call is-board-platform-in-list, apq8084), true) LOCAL_SRC_FILES += power-8084.c endif -ifeq ($(call is-board-platform-in-list, msm8994), true) +ifeq ($(call is-board-platform-in-list,msm8909), true) +LOCAL_SRC_FILES += power-8909.c +endif + +ifeq ($(call is-board-platform-in-list,msm8916), true) +LOCAL_SRC_FILES += power-8916.c +endif + +ifeq ($(call is-board-platform-in-list,msm8992), true) +LOCAL_SRC_FILES += power-8992.c +endif + +ifeq ($(call is-board-platform-in-list,msm8994), true) LOCAL_SRC_FILES += power-8994.c endif -ifeq ($(call is-board-platform-in-list, msm8996), true) +ifeq ($(call is-board-platform-in-list,msm8996), true) LOCAL_SRC_FILES += power-8996.c endif ifeq ($(call is-board-platform-in-list,msm8937), true) -LOCAL_SRC_FILES += power-8952.c +LOCAL_SRC_FILES += power-8937.c endif ifeq ($(call is-board-platform-in-list,msm8952), true) @@ -75,6 +110,18 @@ ifeq ($(call is-board-platform-in-list,msmnile), true) LOCAL_SRC_FILES += power-msmnile.c endif +endif # End of board specific list + +ifneq ($(TARGET_POWERHAL_MODE_EXT),) + LOCAL_CFLAGS += -DMODE_EXT + LOCAL_SRC_FILES += ../../../../$(TARGET_POWERHAL_MODE_EXT) +endif + +ifneq ($(TARGET_POWERHAL_SET_INTERACTIVE_EXT),) + 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 @@ -83,12 +130,20 @@ ifeq ($(TARGET_USES_INTERACTION_BOOST),true) LOCAL_CFLAGS += -DINTERACTION_BOOST endif -LOCAL_MODULE := android.hardware.power-service -LOCAL_INIT_RC := android.hardware.power-service.rc +ifeq ($(call is-board-platform-in-list,trinket), true) +LOCAL_MODULE := power.qcom +LOCAL_MODULE_TAGS := optional +LOCAL_VENDOR_MODULE := true +include $(BUILD_SHARED_LIBRARY) +else +LOCAL_MODULE := android.hardware.power-service-qti +LOCAL_INIT_RC := android.hardware.power-service-qti.rc LOCAL_MODULE_TAGS := optional LOCAL_CFLAGS += -Wno-unused-parameter -Wno-unused-variable LOCAL_VENDOR_MODULE := true LOCAL_VINTF_FRAGMENTS := power.xml + include $(BUILD_EXECUTABLE) endif +endif diff --git a/Power.cpp b/Power.cpp index a28df32..3deedb6 100644 --- a/Power.cpp +++ b/Power.cpp @@ -27,7 +27,7 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define LOG_TAG "QTI PowerHAL" +#define LOG_TAG "android.hardware.power-service-qti" #include "Power.h" @@ -41,9 +41,9 @@ #include using ::aidl::android::hardware::power::BnPower; +using ::aidl::android::hardware::power::Boost; using ::aidl::android::hardware::power::IPower; using ::aidl::android::hardware::power::Mode; -using ::aidl::android::hardware::power::Boost; using ::ndk::ScopedAStatus; using ::ndk::SharedRefBase; @@ -54,13 +54,23 @@ namespace hardware { namespace power { namespace impl { +#ifdef MODE_EXT +extern bool isDeviceSpecificModeSupported(Mode type, bool* _aidl_return); +extern bool setDeviceSpecificMode(Mode type, bool enabled); +#endif + void setInteractive(bool interactive) { - set_interactive(interactive ? 1:0); + set_interactive(interactive ? 1 : 0); } ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { LOG(INFO) << "Power setMode: " << static_cast(type) << " to: " << enabled; - switch(type){ +#ifdef MODE_EXT + if (setDeviceSpecificMode(type, enabled)) { + return ndk::ScopedAStatus::ok(); + } +#endif + switch (type) { #ifdef TAP_TO_WAKE_NODE case Mode::DOUBLE_TAP_TO_WAKE: ::android::base::WriteStringToFile(enabled ? "1" : "0", TAP_TO_WAKE_NODE, true); @@ -99,7 +109,13 @@ ndk::ScopedAStatus Power::setMode(Mode type, bool enabled) { ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) { LOG(INFO) << "Power isModeSupported: " << static_cast(type); - switch(type){ +#ifdef MODE_EXT + if (isDeviceSpecificModeSupported(type, _aidl_return)) { + return ndk::ScopedAStatus::ok(); + } +#endif + + switch (type) { #ifdef TAP_TO_WAKE_NODE case Mode::DOUBLE_TAP_TO_WAKE: #endif @@ -116,8 +132,7 @@ ndk::ScopedAStatus Power::isModeSupported(Mode type, bool* _aidl_return) { } ndk::ScopedAStatus Power::setBoost(Boost type, int32_t durationMs) { - LOG(INFO) << "Power setBoost: " << static_cast(type) - << ", duration: " << durationMs; + LOG(INFO) << "Power setBoost: " << static_cast(type) << ", duration: " << durationMs; return ndk::ScopedAStatus::ok(); } diff --git a/Power.h b/Power.h index c7c42b0..225df88 100644 --- a/Power.h +++ b/Power.h @@ -40,14 +40,12 @@ namespace power { namespace impl { class Power : public BnPower { - public: - Power() : BnPower(){ - power_init(); - } - ndk::ScopedAStatus setMode(Mode type, bool enabled) override; - ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override; - ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override; - ndk::ScopedAStatus isBoostSupported(Boost type, bool* _aidl_return) override; + public: + Power() : BnPower() { power_init(); } + ndk::ScopedAStatus setMode(Mode type, bool enabled) override; + ndk::ScopedAStatus isModeSupported(Mode type, bool* _aidl_return) override; + ndk::ScopedAStatus setBoost(Boost type, int32_t durationMs) override; + ndk::ScopedAStatus isBoostSupported(Boost type, bool* _aidl_return) override; }; } // namespace impl diff --git a/android.hardware.power-service.rc b/android.hardware.power-service-qti.rc similarity index 94% rename from android.hardware.power-service.rc rename to android.hardware.power-service-qti.rc index 7885506..05c4d33 100644 --- a/android.hardware.power-service.rc +++ b/android.hardware.power-service-qti.rc @@ -1,4 +1,4 @@ -service vendor.power /vendor/bin/hw/android.hardware.power-service +service vendor.power /vendor/bin/hw/android.hardware.power-service-qti class hal user system group system diff --git a/hint-data.c b/hint-data.c index 67da77a..7b8cfd2 100644 --- a/hint-data.c +++ b/hint-data.c @@ -27,21 +27,20 @@ * 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) { + ALOGV("hint_id: %lu", hint->hint_id); } diff --git a/hint-data.h b/hint-data.h index 48909c7..629a01e 100644 --- a/hint-data.h +++ b/hint-data.h @@ -28,33 +28,33 @@ */ /* 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 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 -//update NUM_HINTS if hints are added to AOSP -#define NUM_HINTS (POWER_HINT_DISABLE_TOUCH +1) +// update NUM_HINTS if hints are added to AOSP +#define NUM_HINTS (POWER_HINT_DISABLE_TOUCH + 1) -#define VR_MODE_SUSTAINED_PERF_HINT (0x1301) +#define VR_MODE_SUSTAINED_PERF_HINT (0x1301) -struct hint_handles{ +struct hint_handles { int handle; int ref_count; }; @@ -64,6 +64,5 @@ struct hint_data { 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/list.c b/list.c index 0fe8de2..75c74ca 100644 --- a/list.c +++ b/list.c @@ -31,23 +31,12 @@ #include #include +#include #include "list.h" -#include -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; @@ -66,18 +55,12 @@ struct list_node *add_list_node(struct list_node *head, void *data) return new_node; } -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; @@ -107,33 +90,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; - - if (head == NULL) - return; +struct list_node* find_node(struct list_node* head, void* comparison_data) { + struct list_node* current_node = head; - printf("List:\n"); - - while ((current_node = current_node->next)) { - if (current_node->dump) { - current_node->dump(current_node->data); - } - } -} - -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/list.h b/list.h index d68c3df..db666f2 100644 --- a/list.h +++ b/list.h @@ -28,14 +28,12 @@ */ 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); +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); +struct list_node* find_node(struct list_node* head, void* comparison_data); diff --git a/main.cpp b/main.cpp index 8389368..4def7a3 100644 --- a/main.cpp +++ b/main.cpp @@ -42,10 +42,10 @@ int main() { LOG(INFO) << "Instance " << instance; binder_status_t status = AServiceManager_addService(vib->asBinder().get(), instance.c_str()); LOG(INFO) << "Status " << status; - if(status != STATUS_OK){ + if (status != STATUS_OK) { LOG(ERROR) << "Could not register" << instance; } ABinderProcess_joinThreadPool(); return 1; // should not reach -} \ No newline at end of file +} diff --git a/metadata-defs.h b/metadata-defs.h index c464900..bbc5fbf 100644 --- a/metadata-defs.h +++ b/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, 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); +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); diff --git a/metadata-parser.c b/metadata-parser.c index c9122a4..4a8bc30 100644 --- a/metadata-parser.c +++ b/metadata-parser.c @@ -28,55 +28,43 @@ */ #include -#include #include +#include #include "metadata-defs.h" -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; +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; 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) { - 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); - - 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); + 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); + + strlcpy(attribute, attribute_string, bytes_to_copy); + strlcpy(value, attribute_value_delim + 1, value_size); } 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) { @@ -94,21 +82,19 @@ 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) { @@ -126,8 +112,7 @@ 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/performance.h b/performance.h index b7bf34b..1a8fad6 100644 --- a/performance.h +++ b/performance.h @@ -1,4 +1,5 @@ /* Copyright (c) 2012, 2014, The Linux Foundation. All rights reserved. + * Copyright (C) 2018 The LineageOS Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,15 +32,31 @@ 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_DISPLAY_OFF 0x00001040 +#define VENDOR_HINT_DISPLAY_ON 0x00001041 + +#define VENDOR_HINT_SCROLL_BOOST 0x00001080 +#define VENDOR_HINT_FIRST_LAUNCH_BOOST 0x00001081 + +enum SCROLL_BOOST_TYPE { + SCROLL_VERTICAL = 1, + SCROLL_HORIZONTAL = 2, + SCROLL_PANEL_VIEW = 3, + SCROLL_PREFILING = 4, +}; + +enum LAUNCH_BOOST_TYPE { + LAUNCH_BOOST_V1 = 1, + LAUNCH_BOOST_V2 = 2, + LAUNCH_BOOST_V3 = 3, +}; enum SCREEN_DISPLAY_TYPE { DISPLAY_OFF = 0x00FF, @@ -124,16 +141,6 @@ enum SAMPLING_RATE_LVL { MS_20 = 0xBFD, }; -enum ONDEMAND_IO_BUSY_LVL { - IO_BUSY_OFF = 0xC00, - IO_BUSY_ON = 0xC01, -}; - -enum ONDEMAND_SAMPLING_DOWN_FACTOR_LVL { - SAMPLING_DOWN_FACTOR_1 = 0xD01, - SAMPLING_DOWN_FACTOR_4 = 0xD04, -}; - enum INTERACTIVE_TIMER_RATE_LVL { TR_MS_500 = 0xECD, TR_MS_100 = 0xEF5, @@ -184,6 +191,7 @@ enum INTERACTIVE_OPCODES { enum INTERACTIVE_HISPEED_FREQ_LVL { HS_FREQ_1026 = 0xF0A, + HS_FREQ_800 = 0xF08, }; enum INTERACTIVE_HISPEED_LOAD_LVL { @@ -260,6 +268,95 @@ enum CPU7_MAX_FREQ_LVL { CPU7_MAX_FREQ_NONTURBO_MAX = 0x260A, }; +enum SCHED_PREFER_IDLE { + SCHED_PREFER_IDLE_DIS = 0x3E01, +}; + +enum SCHED_MIGRATE_COST_CHNG { + SCHED_MIGRATE_COST_SET = 0x3F01, +}; + +/** + * MPCTL v3 opcodes + */ +/* 0x1 */ +enum POWER_COLLAPSE { + ALL_CPUS_PWR_CLPS_DIS_V3 = 0x40400000, +}; + +/* 0x2 */ +enum CPUFREQ { + MIN_FREQ_BIG_CORE_0 = 0x40800000, + MIN_FREQ_BIG_CORE_0_RESIDX = 0x40802000, + MIN_FREQ_LITTLE_CORE_0 = 0x40800100, + MIN_FREQ_LITTLE_CORE_0_RESIDX = 0x40802100, + MAX_FREQ_BIG_CORE_0 = 0x40804000, + MAX_FREQ_BIG_CORE_0_RESIDX = 0x40806000, + MAX_FREQ_LITTLE_CORE_0 = 0x40804100, + MAX_FREQ_LITTLE_CORE_0_RESIDX = 0x40806100, +}; + +/* 0x3 */ +enum SCHED { + SCHED_BOOST_ON_V3 = 0x40C00000, + SCHED_PREFER_IDLE_DIS_V3 = 0x40C04000, + SCHED_MIGRATE_COST_SET_V3 = 0x40C08000, + SCHED_SMALL_TASK = 0x40C0C000, + SCHED_MOSTLY_IDLE_LOAD = 0x40C10000, + SCHED_MOSTLY_IDLE_NR_RUN = 0x40C14000, + SCHED_GROUP_ON = 0x40C28000, + SCHED_SPILL_NR_RUN = 0x40C2C000, + SCHED_RESTRICT_CLUSTER_SPILL = 0x40C34000, + SCHED_GROUP_UP_MIGRATE = 0x40C54000, + SCHED_GROUP_DOWN_MIGRATE = 0x40C58000, +}; + +/* 0x4 */ +enum CORE_HOTPLUG { + CPUS_ONLINE_MIN_BIG = 0x41000000, + CPUS_ONLINE_MAX_BIG = 0x41004000, + CPUS_ONLINE_MIN_LITTLE = 0x41000100, + CPUS_ONLINE_MAX_LITTLE = 0x41004100, +}; + +/* 0x5 */ +enum INTERACTIVE { + ABOVE_HISPEED_DELAY_BIG = 0x41400000, + ABOVE_HISPEED_DELAY_BIG_RESIDX = 0x41402000, + GO_HISPEED_LOAD_BIG = 0x41410000, + HISPEED_FREQ_BIG = 0x41414000, + TARGET_LOADS_BIG = 0x41420000, + IGNORE_HISPEED_NOTIF_BIG = 0x41438000, + ABOVE_HISPEED_DELAY_LITTLE = 0x41400100, + ABOVE_HISPEED_DELAY_LITTLE_RESIDX = 0x41402100, + GO_HISPEED_LOAD_LITTLE = 0x41410100, + HISPEED_FREQ_LITTLE = 0x41414100, + TARGET_LOADS_LITTLE = 0x41420100, + IGNORE_HISPEED_NOTIF_LITTLE = 0x41438100, +}; + +/* 0x6 */ +enum CPUBW_HWMON { + CPUBW_HWMON_MIN_FREQ = 0x41800000, + CPUBW_HWMON_MIN_FREQ_RESIDX = 0x41802000, + CPUBW_HWMON_HYST_OPT = 0x4180C000, + LOW_POWER_CEIL_MBPS = 0x41810000, + LOW_POWER_IO_PERCENT = 0x41814000, + CPUBW_HWMON_SAMPLE_MS = 0x41820000, +}; + +/* 0xA */ +enum GPU { + GPU_MIN_POWER_LEVEL = 0x42804000, + GPU_MAX_POWER_LEVEL = 0x42808000, + GPU_MIN_FREQ = 0x4280C000, + GPU_MIN_FREQ_RESIDX = 0x4280E000, + GPU_MAX_FREQ = 0x42810000, + GPU_MAX_FREQ_RESIDX = 0x42812000, + GPUBW_MIN_FREQ = 0x42814000, + GPUBW_MAX_FREQ = 0x42818000, +}; + #ifdef __cplusplus } #endif diff --git a/power-6125.c b/power-6125.c index 6f627cb..693b0dc 100644 --- a/power-6125.c +++ b/power-6125.c @@ -29,52 +29,47 @@ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include -#include #include +#include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -#define MIN_VAL(X,Y) ((X>Y)?(Y):(X)) +#define MIN_VAL(X, Y) ((X > Y) ? (Y) : (X)) static int video_encode_hint_sent; pthread_mutex_t camera_hint_mutex = PTHREAD_MUTEX_INITIALIZER; static int camera_hint_ref_count; -static void process_video_encode_hint(void *metadata); -static void process_video_encode_hfr_hint(void *metadata); +static void process_video_encode_hint(void* metadata); +static void process_video_encode_hfr_hint(void* metadata); -int power_hint_override(struct power_module *module, power_hint_t hint, - void *data) -{ - switch(hint) { - case POWER_HINT_VSYNC: - { +int power_hint_override(struct power_module* module, power_hint_t hint, void* data) { + switch (hint) { + case POWER_HINT_VSYNC: { break; } - case POWER_HINT_VIDEO_ENCODE: - { + case POWER_HINT_VIDEO_ENCODE: { process_video_encode_hint(data); return HINT_HANDLED; } /* Using VIDEO_DECODE hint for HR use cases */ - case POWER_HINT_VIDEO_DECODE: - { + case POWER_HINT_VIDEO_DECODE: { process_video_encode_hfr_hint(data); return HINT_HANDLED; } @@ -82,14 +77,12 @@ int power_hint_override(struct power_module *module, power_hint_t hint, return HINT_NONE; } -int set_interactive_override(struct power_module *module, int on) -{ +int set_interactive_override(struct power_module* module, int on) { return HINT_HANDLED; /* to set hints for display on and off. Not in use now */ } /* Video Encode Hint */ -static void process_video_encode_hint(void *metadata) -{ +static void process_video_encode_hint(void* metadata) { char governor[80] = {0}; int resource_values[32] = {0}; int num_resources = 0; @@ -97,19 +90,15 @@ static void process_video_encode_hint(void *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; - } - } + 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. */ @@ -118,8 +107,7 @@ static void process_video_encode_hint(void *metadata) video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; if (metadata) { - if (parse_video_encode_metadata((char *)metadata, - &video_encode_metadata) == -1) { + if (parse_video_encode_metadata((char*)metadata, &video_encode_metadata) == -1) { ALOGE("Error occurred while parsing metadata."); return; } @@ -128,47 +116,37 @@ static void process_video_encode_hint(void *metadata) } if (video_encode_metadata.state == 1) { - if((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && + if ((strncmp(governor, SCHEDUTIL_GOVERNOR, strlen(SCHEDUTIL_GOVERNOR)) == 0) && (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR))) { - /* sample_ms = 20mS - * hispeed load for both clusters = 95 - * sched_load_boost on all cores = -15 - * silver max freq = 1612 */ - int res[] = { - 0x41820000, 0x14, - 0x41440100, 0x5f, - 0x41440000, 0x5f, - 0x40C68100, 0xFFFFFFF1, - 0x40C68110, 0xFFFFFFF1, - 0x40C68120, 0xFFFFFFF1, - 0x40C68130, 0xFFFFFFF1, - 0x40C68000, 0xFFFFFFF1, - 0x40C68010, 0xFFFFFFF1, - 0x40C68020, 0xFFFFFFF1, - 0x40C68030, 0xFFFFFFF1, - 0x40804100, 0x64C, - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } + /* sample_ms = 20mS + * hispeed load for both clusters = 95 + * sched_load_boost on all cores = -15 + * silver max freq = 1612 */ + int res[] = { + 0x41820000, 0x14, 0x41440100, 0x5f, 0x41440000, 0x5f, + 0x40C68100, 0xFFFFFFF1, 0x40C68110, 0xFFFFFFF1, 0x40C68120, 0xFFFFFFF1, + 0x40C68130, 0xFFFFFFF1, 0x40C68000, 0xFFFFFFF1, 0x40C68010, 0xFFFFFFF1, + 0x40C68020, 0xFFFFFFF1, 0x40C68030, 0xFFFFFFF1, 0x40804100, 0x64C, + }; + memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); + num_resources = sizeof(res) / sizeof(res[0]); + pthread_mutex_lock(&camera_hint_mutex); + camera_hint_ref_count++; + if (camera_hint_ref_count == 1) { + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + num_resources); + video_encode_hint_sent = 1; } - pthread_mutex_unlock(&camera_hint_mutex); + } + pthread_mutex_unlock(&camera_hint_mutex); } - } if (video_encode_metadata.state == 0) { - if (((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) || - ((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && - (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR)))) { + } + if (video_encode_metadata.state == 0) { + if (((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && + (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) || + ((strncmp(governor, SCHEDUTIL_GOVERNOR, strlen(SCHEDUTIL_GOVERNOR)) == 0) && + (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR)))) { pthread_mutex_lock(&camera_hint_mutex); camera_hint_ref_count--; if (!camera_hint_ref_count) { @@ -176,15 +154,14 @@ static void process_video_encode_hint(void *metadata) video_encode_hint_sent = 0; } pthread_mutex_unlock(&camera_hint_mutex); - return ; + return; } } return; } /* Video Encode Hint for HFR use cases */ -static void process_video_encode_hfr_hint(void *metadata) -{ +static void process_video_encode_hfr_hint(void* metadata) { char governor[80] = {0}; int resource_values[32] = {0}; int num_resources = 0; @@ -192,19 +169,15 @@ static void process_video_encode_hfr_hint(void *metadata) ALOGI("Got process_video_encode_hint for HFR"); - 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 (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. */ @@ -213,8 +186,7 @@ static void process_video_encode_hfr_hint(void *metadata) video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; if (metadata) { - if (parse_video_encode_metadata((char *)metadata, - &video_encode_metadata) == -1) { + if (parse_video_encode_metadata((char*)metadata, &video_encode_metadata) == -1) { ALOGE("Error occurred while parsing metadata."); return; } @@ -223,36 +195,33 @@ static void process_video_encode_hfr_hint(void *metadata) } if (video_encode_metadata.state == 1) { - if((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && + if ((strncmp(governor, SCHEDUTIL_GOVERNOR, strlen(SCHEDUTIL_GOVERNOR)) == 0) && (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR))) { - /* sample_ms = 20mS - * hispeed load = 95 - * hispeed freq = 1017 */ - int res[] = {0x41820000, 0x14, - 0x41440100, 0x5f, - 0x4143c100, 0x3f9, - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } + /* sample_ms = 20mS + * hispeed load = 95 + * hispeed freq = 1017 */ + int res[] = { + 0x41820000, 0x14, 0x41440100, 0x5f, 0x4143c100, 0x3f9, + }; + memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); + num_resources = sizeof(res) / sizeof(res[0]); + pthread_mutex_lock(&camera_hint_mutex); + camera_hint_ref_count++; + if (camera_hint_ref_count == 1) { + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + num_resources); + video_encode_hint_sent = 1; } - pthread_mutex_unlock(&camera_hint_mutex); + } + pthread_mutex_unlock(&camera_hint_mutex); } - } if (video_encode_metadata.state == 0) { - if (((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) || - ((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && - (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR)))) { + } + if (video_encode_metadata.state == 0) { + if (((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && + (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) || + ((strncmp(governor, SCHEDUTIL_GOVERNOR, strlen(SCHEDUTIL_GOVERNOR)) == 0) && + (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR)))) { pthread_mutex_lock(&camera_hint_mutex); camera_hint_ref_count--; if (!camera_hint_ref_count) { @@ -260,7 +229,7 @@ static void process_video_encode_hfr_hint(void *metadata) video_encode_hint_sent = 0; } pthread_mutex_unlock(&camera_hint_mutex); - return ; + return; } } return; diff --git a/power-660.c b/power-660.c index 6ffe4a4..2f2e8b3 100644 --- a/power-660.c +++ b/power-660.c @@ -29,266 +29,246 @@ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include -#include +#include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -#define MIN_VAL(X,Y) ((X>Y)?(Y):(X)) - -static int saved_interactive_mode = -1; -static int display_hint_sent; static int video_encode_hint_sent; -static int cam_preview_hint_sent; -pthread_mutex_t camera_hint_mutex = PTHREAD_MUTEX_INITIALIZER; -static int camera_hint_ref_count; -static void process_video_encode_hint(void *metadata); -//static void process_cam_preview_hint(void *metadata); +const int kMinInteractiveDuration = 400; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ -/* Returns true is target is SDM630/SDM455 else false*/ -static bool is_target_SDM630() -{ - int fd; - bool is_target_SDM630=false; - 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"); - is_target_SDM630 = false; - } else { - int soc_id = atoi(buf); - if (soc_id == 318 || soc_id == 327 || soc_id == 385) { - is_target_SDM630 = true; /* Above SOCID for SDM630/SDM455 */ - } - } - } - close(fd); - return is_target_SDM630; -} +/** + * Returns true if the target is SDM630/SDM455. + */ +static bool is_target_SDM630(void) { + static int is_SDM630 = -1; + int soc_id; -int power_hint_override(struct power_module *module, power_hint_t hint, - void *data) -{ + if (is_SDM630 >= 0) return is_SDM630; - switch(hint) { - case POWER_HINT_VSYNC: - break; - case POWER_HINT_VIDEO_ENCODE: - { - process_video_encode_hint(data); - return HINT_HANDLED; - } - } - return HINT_NONE; + soc_id = get_soc_id(); + is_SDM630 = soc_id == 318 || soc_id == 327 || soc_id == 385; + + return is_SDM630; } -int set_interactive_override(struct power_module *module, int on) -{ +static int process_video_encode_hint(void* metadata) { char governor[80]; - char tmp_str[NODE_MAX]; - int resource_values[20]; - int num_resources; struct video_encode_metadata_t video_encode_metadata; - int rc; - ALOGI("Got set_interactive hint"); + if (!metadata) return HINT_NONE; - 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 (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; } - if (!on) { - /* Display off. */ - if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - /* - 1. CPUfreq params + /* 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 (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)) { + if (is_target_SDM630()) { + /* + 1. CPUfreq params - hispeed freq for big - 1113Mhz - go hispeed load for big - 95 - above_hispeed_delay for big - 40ms - 2. BusDCVS V2 params + - target loads - 95 + - nr_run - 5 + 2. BusDCVS V2 params - Sample_ms of 10ms - */ - if(is_target_SDM630()){ - int res[] = { 0x41414000, 0x459, - 0x41410000, 0x5F, - 0x41400000, 0x4, - 0x41820000, 0xA }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - } - /* - 1. CPUfreq params + */ + int resource_values[] = { + HISPEED_FREQ_BIG, 0x459, GO_HISPEED_LOAD_BIG, 0x5F, + ABOVE_HISPEED_DELAY_BIG, 0x4, TARGET_LOADS_BIG, 0x5F, + SCHED_SPILL_NR_RUN, 0X5, CPUBW_HWMON_SAMPLE_MS, 0xA}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; + } + } else { + /* + 1. CPUfreq params - hispeed freq for little - 902Mhz - go hispeed load for little - 95 - above_hispeed_delay for little - 40ms - 2. BusDCVS V2 params + 2. BusDCVS V2 params - Sample_ms of 10ms - 3. Sched group upmigrate - 500 - */ - else{ - int res[] = { 0x41414100, 0x386, - 0x41410100, 0x5F, - 0x41400100, 0x4, - 0x41820000, 0xA, - 0x40C54000, 0x1F4}; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - - } - if (!display_hint_sent) { - perform_hint_action(DISPLAY_STATE_HINT_ID, - resource_values, num_resources); - display_hint_sent = 1; + */ + int resource_values[] = { + HISPEED_FREQ_LITTLE, 0x386, GO_HISPEED_LOAD_LITTLE, 0x5F, + ABOVE_HISPEED_DELAY_LITTLE, 0x4, CPUBW_HWMON_SAMPLE_MS, 0xA}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; } - } + } + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + video_encode_hint_sent = 0; + return HINT_HANDLED; + } + } + return HINT_NONE; +} - } else { - /* Display on. */ - if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; - undo_hint_action(DISPLAY_STATE_HINT_ID); - display_hint_sent = 0; - } - } - saved_interactive_mode = !!on; - return HINT_HANDLED; + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kMinInteractiveDuration; + + 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 it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL); } +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; -/* Video Encode Hint */ -static void process_video_encode_hint(void *metadata) -{ - char governor[80]; - int resource_values[20]; - int num_resources; - struct video_encode_metadata_t video_encode_metadata; + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } - ALOGI("Got process_video_encode_hint"); + if (!launch_mode) { + launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST, + kMaxLaunchDuration, LAUNCH_BOOST_V1); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} - 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; - } - } - } +int power_hint_override(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_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; + default: + break; } + return ret_val; +} - /* 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; +int set_interactive_override(int on) { + char governor[80]; - if (metadata) { - if (parse_video_encode_metadata((char *)metadata, - &video_encode_metadata) == -1) { - ALOGE("Error occurred while parsing metadata."); - return; - } - } else { - return; + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; } - if (video_encode_metadata.state == 1) { - if ((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - /* - 1. CPUfreq params + if (!on) { + /* Display off */ + if (is_interactive_governor(governor)) { + if (is_target_SDM630()) { + /* + 1. CPUfreq params - hispeed freq for big - 1113Mhz - go hispeed load for big - 95 - above_hispeed_delay for big - 40ms - - target loads - 95 - - nr_run - 5 - 2. BusDCVS V2 params - - Sample_ms of 10ms - */ - if(is_target_SDM630()){ - int res[] = { 0x41414000, 0x459, - 0x41410000, 0x5F, - 0x41400000, 0x4, - 0x41420000, 0x5F, - 0x40C2C000, 0X5, - 0x41820000, 0xA}; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - - } - /* - 1. CPUfreq params + 2. BusDCVS V2 params + - Sample_ms of 10ms + */ + int resource_values[] = { + HISPEED_FREQ_BIG, 0x459, GO_HISPEED_LOAD_BIG, 0x5F, + ABOVE_HISPEED_DELAY_BIG, 0x4, CPUBW_HWMON_SAMPLE_MS, 0xA}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } else { + /* + 1. CPUfreq params - hispeed freq for little - 902Mhz - go hispeed load for little - 95 - above_hispeed_delay for little - 40ms - 2. BusDCVS V2 params + 2. BusDCVS V2 params - Sample_ms of 10ms - */ - else{ - int res[] = { 0x41414100, 0x386, - 0x41410100, 0x5F, - 0x41400100, 0x4, - 0x41820000, 0xA}; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); + 3. Sched group upmigrate - 500 + */ + int resource_values[] = { + HISPEED_FREQ_LITTLE, 0x386, GO_HISPEED_LOAD_LITTLE, 0x5F, + ABOVE_HISPEED_DELAY_LITTLE, 0x4, CPUBW_HWMON_SAMPLE_MS, 0xA, + SCHED_GROUP_UP_MIGRATE, 0x1F4}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); } - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } - } - pthread_mutex_unlock(&camera_hint_mutex); } - } else if (video_encode_metadata.state == 0) { - if ((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count--; - if (!camera_hint_ref_count) { - undo_hint_action(video_encode_metadata.hint_id); - video_encode_hint_sent = 0; - } - pthread_mutex_unlock(&camera_hint_mutex); - return ; + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); } } - return; + return HINT_HANDLED; } - - diff --git a/power-710.c b/power-710.c index 034a19c..d5c8b52 100644 --- a/power-710.c +++ b/power-710.c @@ -26,74 +26,58 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - - +#include #include -#include -#include -#include #include -#include #include -#include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" static int display_fd; #define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr" -int set_interactive_override(struct power_module *module, int on) -{ - static const char *display_on = "1"; - static const char *display_off = "0"; +int set_interactive_override(int on) { + static const char* display_on = "1"; + static const char* display_off = "0"; char err_buf[80]; static int init_interactive_hint = 0; - static int set_i_count = 0; int rc = 0; - set_i_count ++; - ALOGI("Got set_interactive hint on= %d, count= %d\n", on, set_i_count); - - if (init_interactive_hint == 0) - { - //First time the display is turned off + if (init_interactive_hint == 0) { + // First time the display is turned off display_fd = TEMP_FAILURE_RETRY(open(SYS_DISPLAY_PWR, O_RDWR)); if (display_fd < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); + strerror_r(errno, err_buf, sizeof(err_buf)); ALOGE("Error opening %s: %s\n", SYS_DISPLAY_PWR, err_buf); - } - else + } else init_interactive_hint = 1; - } - else - if (!on ) { - /* Display off. */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); - } + } else if (!on) { + /* Display off */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); } - else { - /* Display on */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); - } + } else { + /* Display on */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); } - - return HINT_HANDLED; /* Don't excecute this code path, not in use */ + } + return HINT_HANDLED; } - - diff --git a/power-8084.c b/power-8084.c index 5d4b6bf..125ce1f 100644 --- a/power-8084.c +++ b/power-8084.c @@ -28,87 +28,255 @@ */ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -static int display_hint_sent; -static int display_hint2_sent; static int first_display_off_hint; -extern int display_boost; -int set_interactive_override(struct power_module *module, int on) -{ +static int process_video_encode_hint(void* metadata) { char governor[80]; + struct video_encode_metadata_t video_encode_metadata; + + 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; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + if (parse_video_encode_metadata((char*)metadata, &video_encode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); return HINT_NONE; } - if (!on) { - /* Display off. */ - /* - * We need to be able to identify the first display off hint - * and release the current lock holder - */ - if (display_boost) { - if (!first_display_off_hint) { - undo_initial_hint_action(); - first_display_off_hint = 1; - } - /* used for all subsequent toggles to the display */ - if (!display_hint2_sent) { - undo_hint_action(DISPLAY_STATE_HINT_ID_2); - display_hint2_sent = 1; - } + if (video_encode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +static int process_video_decode_hint(void* metadata) { + char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - int resource_values[] = {MS_500, SYNC_FREQ_600, OPTIMAL_FREQ_600, THREAD_MIGRATION_SYNC_OFF}; + /* Initialize decode 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 (!display_hint_sent) { - perform_hint_action(DISPLAY_STATE_HINT_ID, - resource_values, sizeof(resource_values)/sizeof(resource_values[0])); - display_hint_sent = 1; - } + if (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); return HINT_HANDLED; } - } else { - /* Display on */ - if (display_boost && display_hint2_sent) { - int resource_values2[] = {CPUS_ONLINE_MIN_2}; - perform_hint_action(DISPLAY_STATE_HINT_ID_2, - resource_values2, sizeof(resource_values2)/sizeof(resource_values2[0])); - display_hint2_sent = 0; + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; } + } + return HINT_NONE; +} - 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; +// clang-format off +/* fling boost: min 3 CPUs, min 1.1 GHz */ +static int resources_interaction_fling_boost[] = { + CPUS_ONLINE_MIN_3, + CPU0_MIN_FREQ_NONTURBO_MAX + 1, + CPU1_MIN_FREQ_NONTURBO_MAX + 1, + CPU2_MIN_FREQ_NONTURBO_MAX + 1, + CPU3_MIN_FREQ_NONTURBO_MAX + 1 +}; - return HINT_HANDLED; +/* interactive boost: min 2 CPUs, min 1.1 GHz */ +static int resources_interaction_boost[] = { + CPUS_ONLINE_MIN_2, + CPU0_MIN_FREQ_NONTURBO_MAX + 1, + CPU1_MIN_FREQ_NONTURBO_MAX + 1, + CPU2_MIN_FREQ_NONTURBO_MAX + 1, + CPU3_MIN_FREQ_NONTURBO_MAX + 1 +}; + +/* lauch boost: min 2 CPUs, full power for 2 CPUs, min 1.5 GHz for the others */ +static int resources_launch[] = { + CPUS_ONLINE_MIN_2, + CPU0_MIN_FREQ_TURBO_MAX, + CPU1_MIN_FREQ_TURBO_MAX, + CPU2_MIN_FREQ_NONTURBO_MAX + 5, + CPU3_MIN_FREQ_NONTURBO_MAX + 5 +}; +// clang-format on + +const int kDefaultInteractiveDuration = 200; /* ms */ +const int kMinFlingDuration = 1500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kDefaultInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; } } - return HINT_NONE; + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + if (duration >= kMinFlingDuration) { + interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost), + resources_interaction_fling_boost); + } else { + interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost); + } +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (!launch_mode) { + launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration, + ARRAY_SIZE(resources_launch), resources_launch); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: + ret_val = process_video_encode_hint(data); + break; + case POWER_HINT_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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 */ + /* + * We need to be able to identify the first display off hint + * and release the current lock holder + */ + if (!first_display_off_hint) { + undo_initial_hint_action(); + first_display_off_hint = 1; + } + /* Used for all subsequent toggles to the display */ + undo_hint_action(DISPLAY_STATE_HINT_ID_2); + if (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + /* Display on */ + int resource_values2[] = {CPUS_ONLINE_MIN_2}; + perform_hint_action(DISPLAY_STATE_HINT_ID_2, resource_values2, + ARRAY_SIZE(resource_values2)); + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + return HINT_HANDLED; } diff --git a/power-8226.c b/power-8226.c index 9f14645..73240c8 100644 --- a/power-8226.c +++ b/power-8226.c @@ -28,38 +28,183 @@ */ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -static int display_hint_sent; +static int process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; -int power_hint_override(struct power_module *module, power_hint_t hint, void *data) -{ - switch(hint) { - case POWER_HINT_INTERACTION: - { - int resources[] = {0x702, 0x20B, 0x30B}; - int duration = 3000; + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } - interaction(duration, sizeof(resources)/sizeof(resources[0]), resources); + /* 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 (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)) { + 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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); return HINT_HANDLED; } } return HINT_NONE; } + +static int process_video_decode_hint(void* metadata) { + char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } + + /* Initialize decode 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 (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +// clang-format off +static int resources_interaction_boost[] = { + CPUS_ONLINE_MIN_2, + 0x20B, + 0x30B +}; +// clang-format on + +const int kDefaultInteractiveDuration = 500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kDefaultInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; + } + } + + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost); +} + +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: + ret_val = process_video_encode_hint(data); + break; + case POWER_HINT_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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 (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + return HINT_HANDLED; +} diff --git a/power-845.c b/power-845.c index 9248f38..3a95c79 100644 --- a/power-845.c +++ b/power-845.c @@ -27,59 +27,60 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include -#include +#include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" static int display_fd; #define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr" -#define CHECK_HANDLE(x) ((x)>0) -#define NUM_PERF_MODES 3 +#define NUM_PERF_MODES 3 + +const int kMinInteractiveDuration = 100; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* 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; + 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_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 } }; +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) { +static inline int get_perfd_hint_id(perf_mode_type_t type) { int i; - for(i=0; i 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 it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL); } -/* Declare function before use */ -void interaction(int duration, int num_args, int opt_list[]); +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; -int power_hint_override(struct power_module *module, power_hint_t hint, void *data) -{ + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (current_mode != NORMAL_MODE) { + ALOGV("%s: ignoring due to other active perf hints", __func__); + } else if (!launch_mode) { + launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST, + kMaxLaunchDuration, LAUNCH_BOOST_V1); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { int ret_val = HINT_NONE; - switch(hint) { + switch (hint) { case POWER_HINT_VIDEO_ENCODE: ret_val = process_video_encode_hint(data); break; @@ -216,59 +261,47 @@ int power_hint_override(struct power_module *module, power_hint_t hint, void *da ret_val = process_perf_hint(data, VR_MODE); break; case POWER_HINT_INTERACTION: - { - int resources[] = {0x40800100, 0x514}; - int duration = 100; - interaction(duration, sizeof(resources)/sizeof(resources[0]), resources); + process_interaction_hint(data); ret_val = HINT_HANDLED; - } - break; + 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 const char *display_on = "1"; - static const char *display_off = "0"; +int set_interactive_override(int on) { + static const char* display_on = "1"; + static const char* display_off = "0"; char err_buf[80]; static int init_interactive_hint = 0; - static int set_i_count = 0; int rc = 0; - set_i_count ++; - ALOGI("Got set_interactive hint on= %d, count= %d\n", on, set_i_count); - - if (init_interactive_hint == 0) - { - //First time the display is turned off + if (init_interactive_hint == 0) { + // First time the display is turned off display_fd = TEMP_FAILURE_RETRY(open(SYS_DISPLAY_PWR, O_RDWR)); if (display_fd < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); + strerror_r(errno, err_buf, sizeof(err_buf)); ALOGE("Error opening %s: %s\n", SYS_DISPLAY_PWR, err_buf); - } - else + } else init_interactive_hint = 1; - } - else - if (!on ) { - /* Display off. */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); - } + } else if (!on) { + /* Display off */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); } - else { - /* Display on */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); - } + } else { + /* Display on */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); } - - return HINT_HANDLED; /* Don't excecute this code path, not in use */ + } + return HINT_HANDLED; } diff --git a/power-8610.c b/power-8610.c index 9f14645..73240c8 100644 --- a/power-8610.c +++ b/power-8610.c @@ -28,38 +28,183 @@ */ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -static int display_hint_sent; +static int process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; -int power_hint_override(struct power_module *module, power_hint_t hint, void *data) -{ - switch(hint) { - case POWER_HINT_INTERACTION: - { - int resources[] = {0x702, 0x20B, 0x30B}; - int duration = 3000; + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } - interaction(duration, sizeof(resources)/sizeof(resources[0]), resources); + /* 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 (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)) { + 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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); return HINT_HANDLED; } } return HINT_NONE; } + +static int process_video_decode_hint(void* metadata) { + char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } + + /* Initialize decode 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 (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +// clang-format off +static int resources_interaction_boost[] = { + CPUS_ONLINE_MIN_2, + 0x20B, + 0x30B +}; +// clang-format on + +const int kDefaultInteractiveDuration = 500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kDefaultInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; + } + } + + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost); +} + +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: + ret_val = process_video_encode_hint(data); + break; + case POWER_HINT_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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 (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + return HINT_HANDLED; +} diff --git a/power-8909.c b/power-8909.c new file mode 100644 index 0000000..c4854d8 --- /dev/null +++ b/power-8909.c @@ -0,0 +1,162 @@ +/* + * 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 "hint-data.h" +#include "metadata-defs.h" +#include "performance.h" +#include "power-common.h" +#include "utils.h" + +static int process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; + + 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; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + + 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)) { + int resource_values[] = {HS_FREQ_800, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +static int process_video_decode_hint(void* metadata) { + char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } + + /* Initialize decode 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 (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +int power_hint_override(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_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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 (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + return HINT_HANDLED; +} diff --git a/power-8916.c b/power-8916.c new file mode 100644 index 0000000..0a6ca2f --- /dev/null +++ b/power-8916.c @@ -0,0 +1,209 @@ +/* + * 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 +#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" + +/** + * Returns true if the target is MSM8916. + */ +static bool is_target_8916(void) { + static int is_8916 = -1; + int soc_id; + + if (is_8916 >= 0) return is_8916; + + soc_id = get_soc_id(); + is_8916 = soc_id == 206 || (soc_id >= 247 && soc_id <= 250); + + return is_8916; +} + +// clang-format off +static int resources_interaction_fling_boost[] = { + ALL_CPUS_PWR_CLPS_DIS, + SCHED_BOOST_ON, + SCHED_PREFER_IDLE_DIS, + 0x20D +}; + +static int resources_interaction_boost[] = { + ALL_CPUS_PWR_CLPS_DIS, + SCHED_PREFER_IDLE_DIS, + 0x20D +}; + +static int resources_launch[] = { + ALL_CPUS_PWR_CLPS_DIS, + SCHED_BOOST_ON, + SCHED_PREFER_IDLE_DIS, + 0x20F, + 0x1C00, + 0x4001, + 0x4101, + 0x4201 +}; +// clang-format on + +const int kDefaultInteractiveDuration = 500; /* ms */ +const int kMinFlingDuration = 1500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kDefaultInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; + } + } + + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + if (duration >= kMinFlingDuration) { + interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost), + resources_interaction_fling_boost); + } else { + interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost); + } +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (!launch_mode) { + launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration, + ARRAY_SIZE(resources_launch), resources_launch); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: /* Do nothing for encode case */ + ret_val = HINT_HANDLED; + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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 (is_target_8916()) { + if (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + if (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_CPU0_50, TR_MS_CPU4_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + return HINT_HANDLED; +} diff --git a/power-8937.c b/power-8937.c new file mode 100644 index 0000000..e3e2de9 --- /dev/null +++ b/power-8937.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 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 + * 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 +#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" + +static int video_encode_hint_sent; + +static int display_fd; +#define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr" + +const int kMinInteractiveDuration = 500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ + +/** + * Returns true if the target is SDM439/SDM429. + */ +static bool is_target_SDM439(void) { + static int is_SDM439 = -1; + int soc_id; + + if (is_SDM439 >= 0) return is_SDM439; + + soc_id = get_soc_id(); + is_SDM439 = soc_id == 353 || soc_id == 363 || soc_id == 354 || soc_id == 364; + + return is_SDM439; +} + +static int process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; + + 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; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + + 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_schedutil_governor(governor)) { + if (is_target_SDM439()) { + /* sample_ms = 10mS + * SLB for Core0 = -6 + * SLB for Core1 = -6 + * SLB for Core2 = -6 + * SLB for Core3 = -6 + * hispeed load = 95 + * hispeed freq = 998Mhz */ + int resource_values[] = {CPUBW_HWMON_SAMPLE_MS, + 0xa, + 0x40c68100, + 0xfffffffa, + 0x40c68110, + 0xfffffffa, + 0x40c68120, + 0xfffffffa, + 0x40c68130, + 0xfffffffa, + 0x41440100, + 0x5f, + 0x4143c100, + 0x3e6}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; + } + } else { + /* sample_ms = 10mS */ + int resource_values[] = {CPUBW_HWMON_SAMPLE_MS, 0xa}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; + } + } + } else if (is_interactive_governor(governor)) { + /* Sched_load and migration_notification disable + * timer rate - 40mS*/ + int resource_values[] = {INT_OP_CLUSTER0_USE_SCHED_LOAD, 0x1, + INT_OP_CLUSTER1_USE_SCHED_LOAD, 0x1, + INT_OP_CLUSTER0_USE_MIGRATION_NOTIF, 0x1, + INT_OP_CLUSTER1_USE_MIGRATION_NOTIF, 0x1, + INT_OP_CLUSTER0_TIMER_RATE, BIG_LITTLE_TR_MS_40, + INT_OP_CLUSTER1_TIMER_RATE, BIG_LITTLE_TR_MS_40}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; + } + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor) || is_schedutil_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + video_encode_hint_sent = 0; + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kMinInteractiveDuration; + + 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 it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL); +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (!launch_mode) { + launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST, + kMaxLaunchDuration, LAUNCH_BOOST_V1); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: + ret_val = process_video_encode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(int on) { + char governor[80]; + int rc = 0; + + static const char* display_on = "1"; + static const char* display_off = "0"; + char err_buf[80]; + static int init_interactive_hint = 0; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } + + if (!on) { + /* Display off */ + if (is_interactive_governor(governor)) { + int resource_values[] = {INT_OP_CLUSTER0_TIMER_RATE, BIG_LITTLE_TR_MS_50, + INT_OP_CLUSTER1_TIMER_RATE, BIG_LITTLE_TR_MS_50, + INT_OP_NOTIFY_ON_MIGRATE, 0x00}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + + if (init_interactive_hint == 0) { + // First time the display is turned off + display_fd = TEMP_FAILURE_RETRY(open(SYS_DISPLAY_PWR, O_RDWR)); + if (display_fd < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error opening %s: %s\n", SYS_DISPLAY_PWR, err_buf); + } else + init_interactive_hint = 1; + } else if (!on) { + /* Display off */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); + } + } else { + /* Display on */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); + } + } + return HINT_HANDLED; +} diff --git a/power-8952.c b/power-8952.c index 1e29c4a..3e7941b 100644 --- a/power-8952.c +++ b/power-8952.c @@ -29,299 +29,143 @@ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include #include -#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -#define MIN_VAL(X,Y) ((X>Y)?(Y):(X)) +static int process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; -static int saved_interactive_mode = -1; -static int display_hint_sent; -static int video_encode_hint_sent; -pthread_mutex_t camera_hint_mutex = PTHREAD_MUTEX_INITIALIZER; -static int camera_hint_ref_count; -static void process_video_encode_hint(void *metadata); -static int display_fd; -#define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr" + if (!metadata) return HINT_NONE; -static bool is_target_SDM439() /* Returns value=1 if target is Hathi else value 0 */ -{ - int fd; - bool is_target_SDM439 = false; - 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"); - is_target_SDM439 = false; - } else { - int soc_id = atoi(buf); - if (soc_id == 353 || soc_id == 363 || soc_id == 354 || soc_id == 364) { - is_target_SDM439 = true; /* Above SOCID for SDM439/429 */ - } - } + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; } - close(fd); - return is_target_SDM439; -} -int power_hint_override(struct power_module *module, power_hint_t hint, - void *data) -{ + /* 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; - switch(hint) { - case POWER_HINT_VSYNC: - break; - case POWER_HINT_VIDEO_ENCODE: - { - process_video_encode_hint(data); + 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)) { + int resource_values[] = {INT_OP_CLUSTER0_USE_SCHED_LOAD, 0x1, + INT_OP_CLUSTER1_USE_SCHED_LOAD, 0x1, + INT_OP_CLUSTER0_USE_MIGRATION_NOTIF, 0x1, + INT_OP_CLUSTER1_USE_MIGRATION_NOTIF, 0x1, + INT_OP_CLUSTER0_TIMER_RATE, BIG_LITTLE_TR_MS_40, + INT_OP_CLUSTER1_TIMER_RATE, BIG_LITTLE_TR_MS_40}; + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); return HINT_HANDLED; } } return HINT_NONE; } -int set_interactive_override(struct power_module *module, int on) -{ +static int process_video_decode_hint(void* metadata) { char governor[80]; - char tmp_str[NODE_MAX]; - struct video_encode_metadata_t video_encode_metadata; - int rc = 0; + struct video_decode_metadata_t video_decode_metadata; - static const char *display_on = "1"; - static const char *display_off = "0"; - char err_buf[80]; - static int init_interactive_hint = 0; - static int set_i_count = 0; + if (!metadata) return HINT_NONE; - 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 (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; } - if (!on) { - /* Display off. */ - if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - int resource_values[] = {INT_OP_CLUSTER0_TIMER_RATE, BIG_LITTLE_TR_MS_50, - INT_OP_CLUSTER1_TIMER_RATE, BIG_LITTLE_TR_MS_50, - INT_OP_NOTIFY_ON_MIGRATE, 0x00}; - - if (!display_hint_sent) { - perform_hint_action(DISPLAY_STATE_HINT_ID, - resource_values, sizeof(resource_values)/sizeof(resource_values[0])); - display_hint_sent = 1; - } - } /* Perf time rate set for CORE0,CORE4 8952 target*/ + /* Initialize decode 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; - } 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; - } - } - saved_interactive_mode = !!on; - - set_i_count ++; - ALOGI("Got set_interactive hint on= %d, count= %d\n", on, set_i_count); + if (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } - if (init_interactive_hint == 0) - { - //First time the display is turned off - display_fd = TEMP_FAILURE_RETRY(open(SYS_DISPLAY_PWR, O_RDWR)); - if (display_fd < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error opening %s: %s\n", SYS_DISPLAY_PWR, err_buf); + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); return HINT_HANDLED; } - else - init_interactive_hint = 1; - } - else - if (!on ) { - /* Display off. */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); - } - } - else { - /* Display on */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); - } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; } - - return HINT_HANDLED; + } + return HINT_NONE; } -/* Video Encode Hint */ -static void process_video_encode_hint(void *metadata) -{ - char governor[80] = {0}; - int resource_values[20] = {0}; - int num_resources = 0; - 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; - } - } - } +int power_hint_override(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_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + default: + break; } + return ret_val; +} - /* 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; +int set_interactive_override(int on) { + char governor[80]; - if (metadata) { - if (parse_video_encode_metadata((char *)metadata, - &video_encode_metadata) == -1) { - ALOGE("Error occurred while parsing metadata."); - return; - } - } else { - return; + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; } - if (video_encode_metadata.state == 1) { - if((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && - (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR))) { - if(is_target_SDM439()) { - /* sample_ms = 10mS - * SLB for Core0 = -6 - * SLB for Core1 = -6 - * SLB for Core2 = -6 - * SLB for Core3 = -6 - * hispeed load = 95 - * hispeed freq = 998Mhz */ - int res[] = {0x41820000, 0xa, - 0x40c68100, 0xfffffffa, - 0x40c68110, 0xfffffffa, - 0x40c68120, 0xfffffffa, - 0x40c68130, 0xfffffffa, - 0x41440100, 0x5f, - 0x4143c100, 0x3e6, - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } - } - pthread_mutex_unlock(&camera_hint_mutex); - } - else { - /* sample_ms = 10mS */ - int res[] = {0x41820000, 0xa, - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } - } - pthread_mutex_unlock(&camera_hint_mutex); - } - } - else if ((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - /* Sched_load and migration_notif*/ - int res[] = {INT_OP_CLUSTER0_USE_SCHED_LOAD, - 0x1, - INT_OP_CLUSTER1_USE_SCHED_LOAD, - 0x1, - INT_OP_CLUSTER0_USE_MIGRATION_NOTIF, - 0x1, - INT_OP_CLUSTER1_USE_MIGRATION_NOTIF, - 0x1, - INT_OP_CLUSTER0_TIMER_RATE, - BIG_LITTLE_TR_MS_40, - INT_OP_CLUSTER1_TIMER_RATE, - BIG_LITTLE_TR_MS_40 - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values,num_resources); - video_encode_hint_sent = 1; - } - pthread_mutex_unlock(&camera_hint_mutex); + if (!on) { + /* Display off */ + if (is_interactive_governor(governor)) { + int resource_values[] = {INT_OP_CLUSTER0_TIMER_RATE, BIG_LITTLE_TR_MS_50, + INT_OP_CLUSTER1_TIMER_RATE, BIG_LITTLE_TR_MS_50, + INT_OP_NOTIFY_ON_MIGRATE, 0x00}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); } - } else if (video_encode_metadata.state == 0) { - if (((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) || - ((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && - (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR)))) { - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count--; - if (!camera_hint_ref_count) { - undo_hint_action(video_encode_metadata.hint_id); - video_encode_hint_sent = 0; - } - pthread_mutex_unlock(&camera_hint_mutex); - return ; + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); } } - return; + return HINT_HANDLED; } - diff --git a/power-8953.c b/power-8953.c index d0750e4..6823d3c 100644 --- a/power-8953.c +++ b/power-8953.c @@ -29,298 +29,261 @@ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include -#include +#include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -#define MIN_VAL(X,Y) ((X>Y)?(Y):(X)) - -static int saved_interactive_mode = -1; -static int display_hint_sent; static int video_encode_hint_sent; -static int cam_preview_hint_sent; - -pthread_mutex_t camera_hint_mutex = PTHREAD_MUTEX_INITIALIZER; -static int camera_hint_ref_count; -static void process_video_encode_hint(void *metadata); -//static void process_cam_preview_hint(void *metadata); static int display_fd; #define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr" -static bool is_target_SDM632() /* Returns value=632 if target is SDM632 else value 0 */ -{ - int fd; - bool is_target_SDM632 = false; - 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"); - is_target_SDM632 = false; - } else { - int soc_id = atoi(buf); - if (soc_id == 349 || soc_id == 350) { - is_target_SDM632 = true; /* Above SOCID for SDM632 */ - } - } - } - close(fd); - return is_target_SDM632; -} +const int kMinInteractiveDuration = 500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ -int power_hint_override(struct power_module *module, power_hint_t hint, - void *data) -{ +/** + * Returns true if the target is SDM632. + */ +static bool is_target_SDM632(void) { + static int is_SDM632 = -1; + int soc_id; - switch(hint) { - case POWER_HINT_VSYNC: - break; - case POWER_HINT_VIDEO_ENCODE: - { - process_video_encode_hint(data); - return HINT_HANDLED; - } - } - return HINT_NONE; + if (is_SDM632 >= 0) return is_SDM632; + + soc_id = get_soc_id(); + is_SDM632 = soc_id == 349 || soc_id == 350; + + return is_SDM632; } -int set_interactive_override(struct power_module *module, int on) -{ +static int process_video_encode_hint(void* metadata) { char governor[80]; - char tmp_str[NODE_MAX]; struct video_encode_metadata_t video_encode_metadata; - int rc = 0; - static const char *display_on = "1"; - static const char *display_off = "0"; - char err_buf[80]; - static int init_interactive_hint = 0; - static int set_i_count = 0; + if (!metadata) return HINT_NONE; - ALOGI("Got set_interactive hint"); + 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; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + + if (parse_video_encode_metadata((char*)metadata, &video_encode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } - 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."); + if (video_encode_metadata.state == 1) { + if (is_schedutil_governor(governor)) { + if (is_target_SDM632()) { + /* sample_ms = 10mS + * SLB for Core0 = -6 + * SLB for Core1 = -6 + * SLB for Core2 = -6 + * SLB for Core3 = -6 + * hispeed load = 95 + * hispeed freq = 1036 */ + int resource_values[] = {CPUBW_HWMON_SAMPLE_MS, + 0xa, + 0x40c68100, + 0xfffffffa, + 0x40c68110, + 0xfffffffa, + 0x40c68120, + 0xfffffffa, + 0x40c68130, + 0xfffffffa, + 0x41440100, + 0x5f, + 0x4143c100, + 0x40c}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; + } + } else { + /* sample_ms = 10mS */ + int resource_values[] = {CPUBW_HWMON_SAMPLE_MS, 0xa}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; return HINT_HANDLED; } } + } else if (is_interactive_governor(governor)) { + /* Sched_load and migration_notification disable + * timer rate - 40mS*/ + int resource_values[] = {INT_OP_CLUSTER0_USE_SCHED_LOAD, 0x1, + INT_OP_CLUSTER0_USE_MIGRATION_NOTIF, 0x1, + INT_OP_CLUSTER0_TIMER_RATE, BIG_LITTLE_TR_MS_40}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; + } + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor) || is_schedutil_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + video_encode_hint_sent = 0; + return HINT_HANDLED; } } + return HINT_NONE; +} - if (!on) { - /* Display off. */ - if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - /* timer rate - 40mS*/ - int resource_values[] = {0x41424000, 0x28, - }; - if (!display_hint_sent) { - perform_hint_action(DISPLAY_STATE_HINT_ID, - resource_values, sizeof(resource_values)/sizeof(resource_values[0])); - display_hint_sent = 1; - } - } /* Perf time rate set for CORE0,CORE4 8952 target*/ +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; - } 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; - } - } - saved_interactive_mode = !!on; - - set_i_count ++; - ALOGI("Got set_interactive hint on= %d, count= %d\n", on, set_i_count); - - if (init_interactive_hint == 0) - { - //First time the display is turned off - display_fd = TEMP_FAILURE_RETRY(open(SYS_DISPLAY_PWR, O_RDWR)); - if (display_fd < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error opening %s: %s\n", SYS_DISPLAY_PWR, err_buf); - return HINT_HANDLED; + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kMinInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; } - else - init_interactive_hint = 1; } - else - if (!on ) { - /* Display off. */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); - } - } - else { - /* Display on */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); - } + + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL); +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; } + launch_mode = 0; + return HINT_HANDLED; + } + if (!launch_mode) { + launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST, + kMaxLaunchDuration, LAUNCH_BOOST_V1); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } return HINT_HANDLED; } +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: + ret_val = process_video_encode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; + default: + break; + } + return ret_val; +} -/* Video Encode Hint */ -static void process_video_encode_hint(void *metadata) -{ - char governor[80] = {0}; - int resource_values[20] = {0}; - int num_resources = 0; - struct video_encode_metadata_t video_encode_metadata; +int set_interactive_override(int on) { + char governor[80]; + int rc = 0; - 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; - } - } - } - } + static const char* display_on = "1"; + static const char* display_off = "0"; + char err_buf[80]; + static int init_interactive_hint = 0; - /* 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 (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } - if (metadata) { - if (parse_video_encode_metadata((char *)metadata, - &video_encode_metadata) == -1) { - ALOGE("Error occurred while parsing metadata."); - return; + if (!on) { + /* Display off */ + if (is_interactive_governor(governor)) { + int resource_values[] = {INT_OP_CLUSTER0_TIMER_RATE, BIG_LITTLE_TR_MS_40}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); } } else { - return; + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } } - if (video_encode_metadata.state == 1) { - if((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && - (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR))) { - if(is_target_SDM632()) { - /* sample_ms = 10mS - * SLB for Core0 = -6 - * SLB for Core1 = -6 - * SLB for Core2 = -6 - * SLB for Core3 = -6 - * hispeed load = 95 - * hispeed freq = 1036 */ - int res[] = {0x41820000, 0xa, - 0x40c68100, 0xfffffffa, - 0x40c68110, 0xfffffffa, - 0x40c68120, 0xfffffffa, - 0x40c68130, 0xfffffffa, - 0x41440100, 0x5f, - 0x4143c100, 0x40c, - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } - } - pthread_mutex_unlock(&camera_hint_mutex); - } - else { - /* sample_ms = 10mS */ - int res[] = {0x41820000, 0xa, - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } - } - pthread_mutex_unlock(&camera_hint_mutex); - } - } - else if ((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - /* Sched_load and migration_notification disable - * timer rate - 40mS*/ - int res[] = {0x41430000, 0x1, - 0x41434000, 0x1, - 0x41424000, 0x28, - }; - memcpy(resource_values, res, MIN_VAL(sizeof(resource_values), sizeof(res))); - num_resources = sizeof(res)/sizeof(res[0]); - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - if (!video_encode_hint_sent) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, num_resources); - video_encode_hint_sent = 1; - } - } - pthread_mutex_unlock(&camera_hint_mutex); + if (init_interactive_hint == 0) { + // First time the display is turned off + display_fd = TEMP_FAILURE_RETRY(open(SYS_DISPLAY_PWR, O_RDWR)); + if (display_fd < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error opening %s: %s\n", SYS_DISPLAY_PWR, err_buf); + } else + init_interactive_hint = 1; + } else if (!on) { + /* Display off */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); } - } else if (video_encode_metadata.state == 0) { - if (((strncmp(governor, INTERACTIVE_GOVERNOR, - strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) || - ((strncmp(governor, SCHEDUTIL_GOVERNOR, - strlen(SCHEDUTIL_GOVERNOR)) == 0) && - (strlen(governor) == strlen(SCHEDUTIL_GOVERNOR)))) { - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count--; - if (!camera_hint_ref_count) { - undo_hint_action(video_encode_metadata.hint_id); - video_encode_hint_sent = 0; - } - pthread_mutex_unlock(&camera_hint_mutex); - return ; + } else { + /* Display on */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); } } - return; + return HINT_HANDLED; } - - diff --git a/power-8960.c b/power-8960.c new file mode 100644 index 0000000..6c29b06 --- /dev/null +++ b/power-8960.c @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2013, 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 process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; + + 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; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + + 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)) { + 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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +static int process_video_decode_hint(void* metadata) { + char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + 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_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 (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +int power_hint_override(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_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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 (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + return HINT_HANDLED; +} diff --git a/power-8974.c b/power-8974.c index 1e56cc3..b33389a 100644 --- a/power-8974.c +++ b/power-8974.c @@ -28,87 +28,271 @@ */ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -static int display_hint_sent; -static int display_hint2_sent; static int first_display_off_hint; -extern int display_boost; -int set_interactive_override(struct power_module *module, int on) -{ +/** + * Returns true if the target is MSM8974AB or MSM8974AC. + */ +static bool is_target_8974pro(void) { + static int is_8974pro = -1; + int soc_id; + + if (is_8974pro >= 0) return is_8974pro; + + soc_id = get_soc_id(); + is_8974pro = soc_id == 194 || (soc_id >= 208 && soc_id <= 218); + + return is_8974pro; +} + +static int process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; + + 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; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + + 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)) { + 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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +static int process_video_decode_hint(void* metadata) { char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + if (!metadata) return HINT_NONE; if (get_scaling_governor(governor, sizeof(governor)) == -1) { ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } + + /* Initialize decode 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 (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +// clang-format off +static int resources_interaction_fling_boost[] = { + CPUS_ONLINE_MIN_3, + 0x20F, + 0x30F, + 0x40F, + 0x50F +}; + +static int resources_interaction_boost[] = { + CPUS_ONLINE_MIN_2, + 0x20F, + 0x30F, + 0x40F, + 0x50F +}; + +static int resources_launch[] = { + CPUS_ONLINE_MIN_3, + CPU0_MIN_FREQ_TURBO_MAX, + CPU1_MIN_FREQ_TURBO_MAX, + CPU2_MIN_FREQ_TURBO_MAX, + CPU3_MIN_FREQ_TURBO_MAX +}; +// clang-format on + +const int kDefaultInteractiveDuration = 500; /* ms */ +const int kMinFlingDuration = 1500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kDefaultInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; + } + } + + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + if (duration >= kMinFlingDuration) { + interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost), + resources_interaction_fling_boost); + } else { + interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost); + } +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (!launch_mode) { + launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration, + ARRAY_SIZE(resources_launch), resources_launch); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: + ret_val = process_video_encode_hint(data); + break; + case POWER_HINT_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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. */ + /* Display off */ /* * We need to be able to identify the first display off hint * and release the current lock holder */ - if (display_boost) { + if (is_target_8974pro()) { if (!first_display_off_hint) { undo_initial_hint_action(); first_display_off_hint = 1; } /* used for all subsequent toggles to the display */ - if (!display_hint2_sent) { - undo_hint_action(DISPLAY_STATE_HINT_ID_2); - display_hint2_sent = 1; - } + undo_hint_action(DISPLAY_STATE_HINT_ID_2); } - - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { - int resource_values[] = {MS_500, SYNC_FREQ_600, OPTIMAL_FREQ_600, 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; + if (is_interactive_governor(governor)) { + int resource_values[] = {TR_MS_50, THREAD_MIGRATION_SYNC_OFF}; + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); } } else { /* Display on */ - if (display_boost && display_hint2_sent) { + if (is_target_8974pro()) { int resource_values2[] = {CPUS_ONLINE_MIN_2}; - perform_hint_action(DISPLAY_STATE_HINT_ID_2, - resource_values2, sizeof(resource_values2)/sizeof(resource_values2[0])); - display_hint2_sent = 0; + perform_hint_action(DISPLAY_STATE_HINT_ID_2, resource_values2, + ARRAY_SIZE(resource_values2)); } - - if ((strncmp(governor, ONDEMAND_GOVERNOR, strlen(ONDEMAND_GOVERNOR)) == 0) && - (strlen(governor) == strlen(ONDEMAND_GOVERNOR))) { + if (is_interactive_governor(governor)) { undo_hint_action(DISPLAY_STATE_HINT_ID); - display_hint_sent = 0; - - return HINT_HANDLED; } } - - return HINT_NONE; + return HINT_HANDLED; } diff --git a/power-8992.c b/power-8992.c new file mode 100644 index 0000000..7dc6eae --- /dev/null +++ b/power-8992.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 +#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" + +static int process_video_encode_hint(void* metadata) { + char governor[80]; + struct video_encode_metadata_t video_encode_metadata; + + 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; + video_encode_metadata.hint_id = DEFAULT_VIDEO_ENCODE_HINT_ID; + + 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)) { + /* sched and cpufreq params + * hispeed freq - 768 MHz + * target load - 90 + * above_hispeed_delay - 40ms + * sched_small_tsk - 50 + */ + int resource_values[] = {0x2C07, 0x2F5A, 0x2704, 0x4032}; + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_encode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +static int process_video_decode_hint(void* metadata) { + char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } + + /* Initialize decode 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 (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +// clang-format off +static int resources_interaction_fling_boost[] = { + ALL_CPUS_PWR_CLPS_DIS, + SCHED_BOOST_ON, + SCHED_PREFER_IDLE_DIS +}; + +static int resources_interaction_boost[] = { + ALL_CPUS_PWR_CLPS_DIS, + SCHED_PREFER_IDLE_DIS +}; + +static int resources_launch[] = { + SCHED_BOOST_ON, + 0x20C +}; +// clang-format on + +const int kDefaultInteractiveDuration = 500; /* ms */ +const int kMinFlingDuration = 1500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kDefaultInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; + } + } + + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + if (duration >= kMinFlingDuration) { + interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost), + resources_interaction_fling_boost); + } else { + interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost); + } +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (!launch_mode) { + launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration, + ARRAY_SIZE(resources_launch), resources_launch); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { + int ret_val = HINT_NONE; + switch (hint) { + case POWER_HINT_VIDEO_ENCODE: + ret_val = process_video_encode_hint(data); + break; + case POWER_HINT_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; + default: + break; + } + return ret_val; +} + +int set_interactive_override(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 (is_interactive_governor(governor)) { + int resource_values[] = {CPUS_ONLINE_MPD_OVERRIDE}; /* 4+0 core config in display off */ + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); + } + } else { + /* Display on */ + if (is_interactive_governor(governor)) { + undo_hint_action(DISPLAY_STATE_HINT_ID); + } + } + return HINT_HANDLED; +} diff --git a/power-8994.c b/power-8994.c index ddde1d8..edbe32c 100644 --- a/power-8994.c +++ b/power-8994.c @@ -28,35 +28,34 @@ */ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" -static int display_hint_sent; - -static int process_video_encode_hint(void *metadata) -{ +static int process_video_encode_hint(void* metadata) { char governor[80]; struct video_encode_metadata_t video_encode_metadata; + if (!metadata) return HINT_NONE; + if (get_scaling_governor(governor, sizeof(governor)) == -1) { ALOGE("Can't obtain scaling governor."); - return HINT_NONE; } @@ -65,19 +64,13 @@ static int process_video_encode_hint(void *metadata) 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 HINT_NONE; - } - } else { + 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 ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + if (is_interactive_governor(governor)) { /* sched and cpufreq params * hispeed freq - 768 MHz * target load - 90 @@ -85,14 +78,12 @@ static int process_video_encode_hint(void *metadata) * sched_small_tsk - 50 */ int resource_values[] = {0x2C07, 0x2F5A, 0x2704, 0x4032}; - - perform_hint_action(video_encode_metadata.hint_id, - resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); return HINT_HANDLED; } } else if (video_encode_metadata.state == 0) { - if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + if (is_interactive_governor(governor)) { undo_hint_action(video_encode_metadata.hint_id); return HINT_HANDLED; } @@ -100,50 +91,171 @@ 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) -{ +static int process_video_decode_hint(void* metadata) { + char governor[80]; + struct video_decode_metadata_t video_decode_metadata; + + if (!metadata) return HINT_NONE; + + if (get_scaling_governor(governor, sizeof(governor)) == -1) { + ALOGE("Can't obtain scaling governor."); + return HINT_NONE; + } + + /* Initialize decode 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 (parse_video_decode_metadata((char*)metadata, &video_decode_metadata) == -1) { + ALOGE("Error occurred while parsing metadata."); + return HINT_NONE; + } + + if (video_decode_metadata.state == 1) { + if (is_interactive_governor(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, + ARRAY_SIZE(resource_values)); + return HINT_HANDLED; + } + } else if (video_decode_metadata.state == 0) { + if (is_interactive_governor(governor)) { + undo_hint_action(video_decode_metadata.hint_id); + return HINT_HANDLED; + } + } + return HINT_NONE; +} + +// clang-format off +static int resources_interaction_fling_boost[] = { + ALL_CPUS_PWR_CLPS_DIS, + SCHED_BOOST_ON, + SCHED_PREFER_IDLE_DIS +}; + +static int resources_interaction_boost[] = { + ALL_CPUS_PWR_CLPS_DIS, + SCHED_PREFER_IDLE_DIS +}; + +static int resources_launch[] = { + SCHED_BOOST_ON, + 0x20C +}; +// clang-format on + +const int kDefaultInteractiveDuration = 500; /* ms */ +const int kMinFlingDuration = 1500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* ms */ + +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kDefaultInteractiveDuration; + + if (data) { + int input_duration = *((int*)data); + if (input_duration > duration) { + duration = (input_duration > kMaxInteractiveDuration) ? kMaxInteractiveDuration + : input_duration; + } + } + + clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec); + + elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec); + // don't hint if it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + if (duration >= kMinFlingDuration) { + interaction(duration, ARRAY_SIZE(resources_interaction_fling_boost), + resources_interaction_fling_boost); + } else { + interaction(duration, ARRAY_SIZE(resources_interaction_boost), resources_interaction_boost); + } +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (!launch_mode) { + launch_handle = interaction_with_handle(launch_handle, kMaxLaunchDuration, + ARRAY_SIZE(resources_launch), resources_launch); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { int ret_val = HINT_NONE; - switch(hint) { + switch (hint) { case POWER_HINT_VIDEO_ENCODE: ret_val = process_video_encode_hint(data); break; + case POWER_HINT_VIDEO_DECODE: + ret_val = process_video_decode_hint(data); + break; + case POWER_HINT_INTERACTION: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); + break; default: break; } return ret_val; } -int set_interactive_override(struct power_module *module, int on) -{ - return HINT_NONE; /* Don't excecute this code path, not in use */ +int set_interactive_override(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, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - int resource_values[] = {}; /* dummy node */ - 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; - } + if (is_interactive_governor(governor)) { + int resource_values[] = {CPUS_ONLINE_MPD_OVERRIDE}; /* 4+0 core config in display off */ + perform_hint_action(DISPLAY_STATE_HINT_ID, resource_values, + ARRAY_SIZE(resource_values)); } } else { /* Display on */ - if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + if (is_interactive_governor(governor)) { undo_hint_action(DISPLAY_STATE_HINT_ID); - display_hint_sent = 0; - return HINT_HANDLED; } } - return HINT_NONE; + return HINT_HANDLED; } diff --git a/power-8996.c b/power-8996.c index 0b1c362..9cc33b6 100644 --- a/power-8996.c +++ b/power-8996.c @@ -28,37 +28,132 @@ */ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" +#include "utils.h" + +#define NUM_PERF_MODES 3 + +static int video_encode_hint_sent; + +const int kMinInteractiveDuration = 500; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMaxLaunchDuration = 5000; /* 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 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; +} -pthread_mutex_t camera_hint_mutex = PTHREAD_MUTEX_INITIALIZER; -static int display_hint_sent; -static int camera_hint_ref_count; +static int switch_mode(perf_mode_type_t mode) { + int hint_id = 0; + static int perfd_mode_handle = -1; -static int process_video_encode_hint(void *metadata) -{ + // 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) { + // enable + if (data) { + ALOGI("Enable request for mode: 0x%x", mode); + // check if mode is current mode + if (current_mode & mode) { + ALOGD("Mode 0x%x already enabled", mode); + return HINT_HANDLED; + } + // enable requested mode + if (0 != switch_mode(current_mode | mode)) { + 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)) { + ALOGD("Mode 0x%x already disabled", mode); + return HINT_HANDLED; + } + // disable requested mode + if (0 != switch_mode(current_mode & ~mode)) { + ALOGE("Couldn't disable mode 0x%x", mode); + return HINT_NONE; + } + current_mode &= ~mode; + ALOGI("Current mode is 0x%x", current_mode); + } + + return HINT_HANDLED; +} + +static int process_video_encode_hint(void* metadata) { char governor[80]; struct video_encode_metadata_t video_encode_metadata; + if (!metadata) return HINT_NONE; + if (get_scaling_governor(governor, sizeof(governor)) == -1) { ALOGE("Can't obtain scaling governor."); - return HINT_NONE; } @@ -67,19 +162,13 @@ static int process_video_encode_hint(void *metadata) 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 HINT_NONE; - } - } else { + 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 ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { + if (is_interactive_governor(governor)) { /* 1. cpufreq params * -above_hispeed_delay for LVT - 40ms * -go hispeed load for LVT - 95 @@ -95,85 +184,120 @@ static int process_video_encode_hint(void *metadata) * 3. hysteresis optimization * -bus dcvs hysteresis tuning * -sample_ms of 10 ms - * -sLVT hispeed freq to 806MHz */ - int resource_values[] = {0x41400000, 0x4, 0x41410000, 0x5F, 0x41414000, 0x326, - 0x41420000, 0x5A, 0x41400100, 0x4, 0x41410100, 0x5F, 0x41414100, 0x22C, 0x41420100, 0x5A, - 0x41810000, 0x9C4, 0x41814000, 0x32, 0x4180C000, 0x0, 0x41820000, 0xA}; - - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count++; - if (camera_hint_ref_count == 1) { - perform_hint_action(video_encode_metadata.hint_id, - resource_values, sizeof(resource_values)/sizeof(resource_values[0])); + int resource_values[] = { + ABOVE_HISPEED_DELAY_BIG, 0x4, GO_HISPEED_LOAD_BIG, 0x5F, + HISPEED_FREQ_BIG, 0x326, TARGET_LOADS_BIG, 0x5A, + ABOVE_HISPEED_DELAY_LITTLE, 0x4, GO_HISPEED_LOAD_LITTLE, 0x5F, + HISPEED_FREQ_LITTLE, 0x22C, TARGET_LOADS_LITTLE, 0x5A, + LOW_POWER_CEIL_MBPS, 0x9C4, LOW_POWER_IO_PERCENT, 0x32, + CPUBW_HWMON_HYST_OPT, 0x0, CPUBW_HWMON_SAMPLE_MS, 0xA}; + if (!video_encode_hint_sent) { + perform_hint_action(video_encode_metadata.hint_id, resource_values, + ARRAY_SIZE(resource_values)); + video_encode_hint_sent = 1; + return HINT_HANDLED; } - pthread_mutex_unlock(&camera_hint_mutex); - ALOGI("Video Encode hint start"); - return HINT_HANDLED; } } else if (video_encode_metadata.state == 0) { - if ((strncmp(governor, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - pthread_mutex_lock(&camera_hint_mutex); - camera_hint_ref_count--; - if (!camera_hint_ref_count) { - undo_hint_action(video_encode_metadata.hint_id); - } - pthread_mutex_unlock(&camera_hint_mutex); - - ALOGI("Video Encode hint stop"); + if (is_interactive_governor(governor)) { + undo_hint_action(video_encode_metadata.hint_id); + video_encode_hint_sent = 0; return HINT_HANDLED; } } return HINT_NONE; } -int power_hint_override(struct power_module *module, power_hint_t hint, void *data) -{ +static void process_interaction_hint(void* data) { + static struct timespec s_previous_boost_timespec; + static int s_previous_duration = 0; + + struct timespec cur_boost_timespec; + long long elapsed_time; + int duration = kMinInteractiveDuration; + + if (current_mode != NORMAL_MODE) { + ALOGV("%s: ignoring due to other active perf hints", __func__); + return; + } + + 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 it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL); +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (current_mode != NORMAL_MODE) { + ALOGV("%s: ignoring due to other active perf hints", __func__); + } else if (!launch_mode) { + launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST, + kMaxLaunchDuration, LAUNCH_BOOST_V1); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { int ret_val = HINT_NONE; - switch(hint) { + 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: + process_interaction_hint(data); + ret_val = HINT_HANDLED; + 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) -{ +int set_interactive_override(int on) { return HINT_HANDLED; /* Don't excecute this code path, not in use */ - 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, INTERACTIVE_GOVERNOR, strlen(INTERACTIVE_GOVERNOR)) == 0) && - (strlen(governor) == strlen(INTERACTIVE_GOVERNOR))) { - int resource_values[] = {}; /* dummy node */ - if (!display_hint_sent) { - perform_hint_action(DISPLAY_STATE_HINT_ID, - resource_values, sizeof(resource_values)/sizeof(resource_values[0])); - display_hint_sent = 1; - ALOGI("Display Off hint start"); - return HINT_HANDLED; - } - } - } 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; - ALOGI("Display Off hint stop"); - return HINT_HANDLED; - } - } - return HINT_NONE; } diff --git a/power-8998.c b/power-8998.c index d3d81c9..4f59b4c 100644 --- a/power-8998.c +++ b/power-8998.c @@ -28,54 +28,55 @@ */ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include -#include +#include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" -#include "metadata-defs.h" #include "hint-data.h" +#include "metadata-defs.h" #include "performance.h" #include "power-common.h" -#include "powerhintparser.h" +#include "utils.h" + +#define NUM_PERF_MODES 3 -#define CHECK_HANDLE(x) ((x)>0) -#define NUM_PERF_MODES 3 +const int kMaxLaunchDuration = 5000; /* ms */ +const int kMaxInteractiveDuration = 5000; /* ms */ +const int kMinInteractiveDuration = 400; /* 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; + 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_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 } }; +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) { +static inline int get_perfd_hint_id(perf_mode_type_t type) { int i; - for(i=0; i 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 it's been less than 250ms since last boost + // also detect if we're doing anything resembling a fling + // support additional boosting in case of flings + if (elapsed_time < 250000 && duration <= 750) { + return; + } + s_previous_boost_timespec = cur_boost_timespec; + s_previous_duration = duration; + + perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL); +} + +static int process_activity_launch_hint(void* data) { + static int launch_handle = -1; + static int launch_mode = 0; + + // release lock early if launch has finished + if (!data) { + if (CHECK_HANDLE(launch_handle)) { + release_request(launch_handle); + launch_handle = -1; + } + launch_mode = 0; + return HINT_HANDLED; + } + + if (current_mode != NORMAL_MODE) { + ALOGV("%s: ignoring due to other active perf hints", __func__); + } else if (!launch_mode) { + launch_handle = perf_hint_enable_with_type(VENDOR_HINT_FIRST_LAUNCH_BOOST, + kMaxLaunchDuration, LAUNCH_BOOST_V1); + if (!CHECK_HANDLE(launch_handle)) { + ALOGE("Failed to perform launch boost"); + return HINT_NONE; + } + launch_mode = 1; + } + return HINT_HANDLED; +} + +int power_hint_override(power_hint_t hint, void* data) { int ret_val = HINT_NONE; - switch(hint) { + switch (hint) { case POWER_HINT_VIDEO_ENCODE: ret_val = process_video_encode_hint(data); break; @@ -208,11 +257,11 @@ int power_hint_override(struct power_module *module, power_hint_t hint, void *da ret_val = process_perf_hint(data, VR_MODE); break; case POWER_HINT_INTERACTION: - pthread_mutex_lock(&perf_mode_switch_lock); - if (current_mode != NORMAL_MODE) { - ret_val = HINT_HANDLED; - } - pthread_mutex_unlock(&perf_mode_switch_lock); + process_interaction_hint(data); + ret_val = HINT_HANDLED; + break; + case POWER_HINT_LAUNCH: + ret_val = process_activity_launch_hint(data); break; default: break; @@ -220,7 +269,6 @@ 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(int on) { return HINT_HANDLED; /* Don't excecute this code path, not in use */ } diff --git a/power-common-old.h b/power-common-old.h index e374e46..defd53e 100644 --- a/power-common-old.h +++ b/power-common-old.h @@ -42,9 +42,4 @@ #define HINT_HANDLED (0) #define HINT_NONE (-1) -enum CPU_GOV_CHECK { - CPU0 = 0, - CPU1 = 1, - CPU2 = 2, - CPU3 = 3 -}; +enum CPU_GOV_CHECK { CPU0 = 0, CPU1 = 1, CPU2 = 2, CPU3 = 3 }; diff --git a/power-common.c b/power-common.c index 0101bea..24c0df6 100644 --- a/power-common.c +++ b/power-common.c @@ -29,96 +29,85 @@ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" #include "hint-data.h" #include "performance.h" #include "power-common.h" +#include "utils.h" static struct hint_handles handles[NUM_HINTS]; -void power_init() -{ +void power_init() { ALOGI("Initing"); - for (int i=0; i 0) - handles[hint].ref_count++; - } - else - if (handles[hint].handle > 0) + if (handles[hint].handle > 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 + } else { ALOGE("Lock for hint: %X was not acquired, cannot be released", hint); - break; + } + } + break; + default: + break; } } -int __attribute__ ((weak)) set_interactive_override(int on) -{ +int __attribute__((weak)) set_interactive_override(int on) { return HINT_NONE; } -void set_interactive(int on) -{ +#ifdef SET_INTERACTIVE_EXT +extern void power_set_interactive_ext(int on); +#endif + +void set_interactive(int on) { + static int display_hint_sent; + if (!on) { /* Send Display OFF hint to perf HAL */ perf_hint_enable(VENDOR_HINT_DISPLAY_OFF, 0); @@ -127,9 +116,21 @@ void set_interactive(int on) perf_hint_enable(VENDOR_HINT_DISPLAY_ON, 0); } + /** + * Ignore consecutive display-off hints + * Consecutive display-on hints are already handled + */ + if (display_hint_sent && !on) return; + + display_hint_sent = !on; + +#ifdef SET_INTERACTIVE_EXT + power_set_interactive_ext(on); +#endif + if (set_interactive_override(on) == HINT_HANDLED) { return; + } else { + ALOGI("Hint not handled in set_interactive_override"); } - - ALOGI("Got set_interactive hint"); } diff --git a/power-common.h b/power-common.h index 697302a..d8f494a 100644 --- a/power-common.h +++ b/power-common.h @@ -33,17 +33,7 @@ extern "C" { #endif -#define NODE_MAX (64) - -#define SCALING_GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" -#define DCVS_CPU0_SLACK_MAX_NODE "/sys/module/msm_dcvs/cores/cpu0/slack_time_max_us" -#define DCVS_CPU0_SLACK_MIN_NODE "/sys/module/msm_dcvs/cores/cpu0/slack_time_min_us" -#define MPDECISION_SLACK_MAX_NODE "/sys/module/msm_mpdecision/slack_time_max_us" -#define MPDECISION_SLACK_MIN_NODE "/sys/module/msm_mpdecision/slack_time_min_us" -#define SCALING_MIN_FREQ "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq" -#define ONDEMAND_GOVERNOR "ondemand" #define INTERACTIVE_GOVERNOR "interactive" -#define MSMDCVS_GOVERNOR "msm-dcvs" #define SCHEDUTIL_GOVERNOR "schedutil" #define HINT_HANDLED (0) @@ -51,19 +41,17 @@ extern "C" { #include -enum CPU_GOV_CHECK { - CPU0 = 0, - CPU1 = 1, - CPU2 = 2, - CPU3 = 3 -}; +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 power_hint(power_hint_t hint, void* data); void set_interactive(int on); +#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0])) +#define CHECK_HANDLE(x) ((x) > 0) + #ifdef __cplusplus } #endif -#endif //__POWER_COMMON_H___ +#endif //__POWER_COMMON_H___ diff --git a/power-msmnile.c b/power-msmnile.c index 7000079..58a21f5 100644 --- a/power-msmnile.c +++ b/power-msmnile.c @@ -27,82 +27,68 @@ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - #define LOG_NIDEBUG 0 +#include #include -#include -#include #include -#include -#include #include +#include +#include +#include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include +#include "performance.h" #include "power-common.h" +#include "utils.h" static int display_fd; #define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr" -int set_interactive_override(int on) -{ - static const char *display_on = "1"; - static const char *display_off = "0"; +int set_interactive_override(int on) { + static const char* display_on = "1"; + static const char* display_off = "0"; char err_buf[80]; static int init_interactive_hint = 0; - static int set_i_count = 0; int rc = 0; - set_i_count ++; - ALOGI("Got set_interactive hint on= %d, count= %d\n", on, set_i_count); - - if (init_interactive_hint == 0) - { - //First time the display is turned off + if (init_interactive_hint == 0) { + // First time the display is turned off display_fd = TEMP_FAILURE_RETRY(open(SYS_DISPLAY_PWR, O_RDWR)); if (display_fd < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); + strerror_r(errno, err_buf, sizeof(err_buf)); ALOGE("Error opening %s: %s\n", SYS_DISPLAY_PWR, err_buf); - } - else + } else init_interactive_hint = 1; - } - else - if (!on ) { - /* Display off. */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); - } + } else if (!on) { + /* Display off */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_off, strlen(display_off))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_off, SYS_DISPLAY_PWR, err_buf); } - else { - /* Display on */ - rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); - if (rc < 0) { - strerror_r(errno,err_buf,sizeof(err_buf)); - ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); - } + } else { + /* Display on */ + rc = TEMP_FAILURE_RETRY(write(display_fd, display_on, strlen(display_on))); + if (rc < 0) { + strerror_r(errno, err_buf, sizeof(err_buf)); + ALOGE("Error writing %s to %s: %s\n", display_on, SYS_DISPLAY_PWR, err_buf); } - + } return HINT_HANDLED; } -void interaction(int duration, int num_args, int opt_list[]); - -int power_hint_override(power_hint_t hint, void *data) -{ +int power_hint_override(power_hint_t hint, void* data) { int ret_val = HINT_NONE; - switch(hint) { - case POWER_HINT_INTERACTION: - { - int resources[] = {0x40800100, 0x514}; + switch (hint) { + case POWER_HINT_INTERACTION: { + int resources[] = {MIN_FREQ_LITTLE_CORE_0, 0x514}; int duration = 100; - interaction(duration, sizeof(resources)/sizeof(resources[0]), resources); + interaction(duration, ARRAY_SIZE(resources), resources); ret_val = HINT_HANDLED; } default: diff --git a/power.c b/power.c index 7a09d8b..b68ffea 100644 --- a/power.c +++ b/power.c @@ -29,104 +29,91 @@ #define LOG_NIDEBUG 0 +#include #include -#include -#include -#include #include -#include #include +#include +#include +#include #include #define LOG_TAG "QTI PowerHAL" -#include #include #include +#include -#include "utils.h" #include "hint-data.h" #include "performance.h" #include "power-common-old.h" +#include "utils.h" static struct hint_handles handles[NUM_HINTS]; -static int power_device_open(const hw_module_t* module, const char* name, - hw_device_t** device); +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, + .open = power_device_open, }; -static void power_init(struct power_module *module) -{ +static void power_init(struct power_module* module) { 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 + if (handles[hint].handle > 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; + break; } } -int __attribute__ ((weak)) set_interactive_override(struct power_module *module, int on) -{ +int __attribute__((weak)) set_interactive_override(struct power_module* module, int on) { return HINT_NONE; } -void set_interactive(struct power_module *module, int on) -{ +void set_interactive(struct power_module* module, int on) { if (!on) { /* Send Display OFF hint to perf HAL */ perf_hint_enable(VENDOR_HINT_DISPLAY_OFF, 0); @@ -142,18 +129,16 @@ void set_interactive(struct power_module *module, int on) ALOGI("Got set_interactive hint"); } -static int power_device_open(const hw_module_t* module, const char* name, - hw_device_t** device) -{ +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)); + power_module_t* dev = (power_module_t*)malloc(sizeof(*dev)); - if(dev) { + if (dev) { memset(dev, 0, sizeof(*dev)); - if(dev) { + if (dev) { /* initialize the fields */ dev->common.module_api_version = POWER_MODULE_API_VERSION_0_2; dev->common.tag = HARDWARE_DEVICE_TAG; @@ -161,17 +146,14 @@ static int power_device_open(const hw_module_t* module, const char* name, dev->powerHint = power_hint; dev->setInteractive = set_interactive; /* At the moment we support 0.2 APIs */ - dev->setFeature = NULL, - dev->get_number_of_platform_modes = NULL, - dev->get_platform_low_power_stats = NULL, - dev->get_voter_list = NULL, - *device = (hw_device_t*)dev; + dev->setFeature = NULL, 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 { + } else { status = -ENOMEM; } } @@ -181,17 +163,18 @@ static int power_device_open(const hw_module_t* module, const char* name, } struct power_module HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = POWER_MODULE_API_VERSION_0_2, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = POWER_HARDWARE_MODULE_ID, - .name = "QTI Power HAL", - .author = "QTI", - .methods = &power_module_methods, - }, - - .init = power_init, - .powerHint = power_hint, - .setInteractive = set_interactive, + .common = + { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = POWER_MODULE_API_VERSION_0_2, + .hal_api_version = HARDWARE_HAL_API_VERSION, + .id = POWER_HARDWARE_MODULE_ID, + .name = "QTI Power HAL", + .author = "QTI", + .methods = &power_module_methods, + }, + + .init = power_init, + .powerHint = power_hint, + .setInteractive = set_interactive, }; diff --git a/powerhintparser.c b/powerhintparser.c deleted file mode 100644 index 6d8646f..0000000 --- a/powerhintparser.c +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright (c) 2016-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. - * - */ -#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; - int opcode = 0, value = 0, type = 0; - int numParams = 0; - static int hintCount; - - if(access(POWERHINT_XML, F_OK) < 0) { - return -1; - } - - doc = xmlReadFile(POWERHINT_XML, "UTF-8", XML_PARSE_RECOVER); - if(!doc) { - ALOGE("Document not parsed successfully"); - return -1; - } - - currNode = xmlDocGetRootElement(doc); - if(!currNode) { - ALOGE("Empty document"); - xmlFreeDoc(doc); - xmlCleanupParser(); - return -1; - } - - // Confirm the root-element of the tree - if(xmlStrcmp(currNode->name, BAD_CAST "Powerhint")) { - ALOGE("document of the wrong type, root node != root"); - xmlFreeDoc(doc); - xmlCleanupParser(); - return -1; - } - - currNode = currNode->xmlChildrenNode; - - 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); - 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); - } - - 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) - { - ALOGE("xmlGetProp failed on opcode"); - xmlFreeDoc(doc); - xmlCleanupParser(); - return -1; - } - opcode = strtol(opcode_str, NULL, 16); - } - if(xmlHasProp(node, BAD_CAST "value")) { - value_str = (const char*)xmlGetProp(node, BAD_CAST "value"); - if (value_str == NULL) - { - ALOGE("xmlGetProp failed on value"); - xmlFreeDoc(doc); - xmlCleanupParser(); - return -1; - } - value = strtol(value_str, NULL, 16); - } - 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); - opcode = value = 0; - break; - } - } - - opcode = value = 0; - } - node = node->next; - } - powerhint[hintCount].type = type; - powerhint[hintCount].numParams = numParams; - numParams = 0; - } - hintCount++; - } - - xmlFreeDoc(doc); - xmlCleanupParser(); - return 0; -} - -int* getPowerhint(int hint_id, int *params) { - - int *result = NULL; - - if(!hint_id) - return result; - - 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 j = 0; j < *params; j++) - ALOGI("Powerhal resource again%x = \n", result[j]);*/ - - return result; -} diff --git a/powerhintparser.h b/powerhintparser.h deleted file mode 100644 index 5f9cbe6..0000000 --- a/powerhintparser.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (c) 2016, 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 __POWERHINTPARSER__ -#define __POWERHINTPARSER__ - -#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; - -static perflock_param_t powerhint[MAX_HINT]; - -int parsePowerhintXML(); -int *getPowerhint(int, int*); - -#endif /* __POWERHINTPARSER__ */ diff --git a/utils.c b/utils.c index f7f2251..44f1527 100644 --- a/utils.c +++ b/utils.c @@ -29,53 +29,66 @@ #define LOG_NIDEBUG 0 #include -#include #include +#include #include #include #include -#include "utils.h" -#include "list.h" #include "hint-data.h" +#include "list.h" #include "power-common.h" +#include "utils.h" #define LOG_TAG "QTI PowerHAL" -#include +#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" -}; +#define SOC_ID_0 "/sys/devices/soc0/soc_id" +#define SOC_ID_1 "/sys/devices/system/soc/soc0/id" + +const char* scaling_gov_path[8] = {"/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", + "/sys/devices/system/cpu/cpu4/cpufreq/scaling_governor", + "/sys/devices/system/cpu/cpu5/cpufreq/scaling_governor", + "/sys/devices/system/cpu/cpu6/cpufreq/scaling_governor", + "/sys/devices/system/cpu/cpu7/cpufreq/scaling_governor"}; #define PERF_HAL_PATH "libqti-perfd-client.so" -static void *qcopt_handle; -static int (*perf_lock_acq)(int handle, int duration, - int list[], int numArgs); +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 int (*perf_hint)(int, const char*, int, int); static struct list_node active_hint_list_head; -const char *pkg = "QTI PowerHAL"; +const char* pkg = "QTI PowerHAL"; -static void *get_qcopt_handle() -{ - void *handle = NULL; +static void* get_qcopt_handle() { + char qcopt_lib_path[PATH_MAX] = {0}; + void* handle = NULL; dlerror(); - handle = dlopen(PERF_HAL_PATH, RTLD_NOW); + if (property_get("ro.vendor.extension_library", qcopt_lib_path, NULL)) { + handle = dlopen(qcopt_lib_path, RTLD_NOW); + if (!handle) { + ALOGE("Unable to open %s: %s\n", qcopt_lib_path, dlerror()); + } + } if (!handle) { - ALOGE("Unable to open %s: %s\n", PERF_HAL_PATH, - dlerror()); + handle = dlopen(PERF_HAL_PATH, RTLD_NOW); + if (!handle) { + 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) { @@ -105,16 +118,13 @@ 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(const char* path, char* s, int num_bytes) { char buf[80]; int count; int ret = 0; @@ -141,8 +151,7 @@ int sysfs_read(char *path, char *s, int num_bytes) return ret; } -int sysfs_write(char *path, char *s) -{ +int sysfs_write(const char* path, char* s) { char buf[80]; int len; int ret = 0; @@ -151,7 +160,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)); @@ -167,30 +176,19 @@ 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) { - // Can't obtain the scaling governor. Return. - return -1; - } else { - // Strip newline at the end. - int len = strlen(governor); - - len--; - - while (len >= 0 && (governor[len] == '\n' || governor[len] == '\r')) - governor[len--] = '\0'; +int get_scaling_governor(char governor[], int size) { + for (size_t i = 0; i < ARRAY_SIZE(scaling_gov_path); i++) { + if (get_scaling_governor_check_cores(governor, size, i) == 0) { + // Obtained the scaling governor. Return. + return 0; + } } - return 0; + return -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) { +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; } @@ -198,138 +196,135 @@ 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[]) -{ -#ifdef INTERACTION_BOOST +int is_schedutil_governor(char* governor) { + if (strncmp(governor, SCHEDUTIL_GOVERNOR, (strlen(SCHEDUTIL_GOVERNOR) + 1)) == 0) return 1; + return 0; +} + +#ifndef INTERACTION_BOOST +void interaction(int duration, int num_args, int opt_list[]) { +#else +void interaction(int duration, int num_args, int opt_list[]) { static int lock_handle = 0; - if (duration < 0 || num_args < 1 || opt_list[0] == NULL) - return; + if (duration < 0 || num_args < 1 || opt_list[0] == 0) 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] == NULL) - 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] == 0) 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, pkg, duration, -1); - if (lock_handle == -1) - ALOGE("Failed to acquire lock for hint_id: %X.", hint_id); + 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) -{ - 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 perform_hint_action(int hint_id, int resource_values[], int num_resources) { + if (qcopt_handle && perf_lock_acq) { + /* Acquire an indefinite lock for the requested 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)); - - 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; - } - - new_hint->hint_id = hint_id; - new_hint->perflock_handle = lock_handle; - - 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); - - ALOGE("Failed to process hint."); - } - } else { - /* Can't keep track of this lock. Release it. */ - if (perf_lock_rel) - perf_lock_rel(lock_handle); - - ALOGE("Failed to process hint."); - } - } + if (lock_handle == -1) { + ALOGE("Failed to acquire lock."); + return -EINVAL; + } + + /* Add this handle to our internal hint-list. */ + struct hint_data* new_hint = (struct hint_data*)malloc(sizeof(struct hint_data)); + + if (!new_hint) { + /* Can't keep track of this lock. Release it. */ + if (perf_lock_rel) perf_lock_rel(lock_handle); + ALOGE("Failed to process hint."); + return -ENOMEM; + } + + 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; + } + + new_hint->hint_id = hint_id; + new_hint->perflock_handle = lock_handle; + + 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); + ALOGE("Failed to process hint."); + return -ENOMEM; } } + return 0; } -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) @@ -353,11 +348,38 @@ 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); } } } + +int get_soc_id(void) { + int fd; + int soc_id = -1; + char buf[10] = {0}; + + if (!access(SOC_ID_0, F_OK)) + fd = open(SOC_ID_0, O_RDONLY); + else + fd = open(SOC_ID_1, O_RDONLY); + + if (fd >= 0) { + if (read(fd, buf, sizeof(buf) - 1) == -1) + ALOGW("Unable to read soc_id"); + else + soc_id = atoi(buf); + } + + close(fd); + return soc_id; +} + +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/utils.h b/utils.h index 4c3dc7f..3acb0f7 100644 --- a/utils.h +++ b/utils.h @@ -29,19 +29,21 @@ #include -int sysfs_read(char *path, char *s, int num_bytes); -int sysfs_write(char *path, char *s); +int sysfs_read(const char* path, char* s, int num_bytes); +int sysfs_write(const 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*); +int is_schedutil_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); +int perform_hint_action(int hint_id, int resource_values[], int num_resources); void undo_hint_action(int hint_id); +void undo_initial_hint_action(); void release_request(int lock_handle); +void interaction(int duration, int num_args, int opt_list[]); 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); +int get_soc_id(void);