sdm710-common: Import QTI Power HAL from Lineage

* 0db671a262
 * https://github.com/LineageOS/android_hardware_lineage_interfaces/tree/lineage-17.1/power/1.0
 * rootdir: Disable vendor.power-hal-1-0
 * sepolicy: Lable android.hardware.power@1.2-service-qti

Signed-off-by: SamarV-121 <samarvispute121@gmail.com>
This commit is contained in:
SamarV-121 2020-03-22 15:38:45 +05:30
parent 530df18b17
commit d07301de0a
28 changed files with 947 additions and 791 deletions

4
interfaces/Android.bp Normal file
View file

@ -0,0 +1,4 @@
hidl_package_root {
name: "vendor.lineage",
path: "device/realme/sdm710-common/interfaces/",
}

View file

@ -0,0 +1,19 @@
// This file is autogenerated by hidl-gen -Landroidbp.
hidl_interface {
name: "vendor.lineage.power@1.0",
root: "vendor.lineage",
srcs: [
"types.hal",
"ILineagePower.hal",
],
interfaces: [
"android.hidl.base@1.0",
],
types: [
"LineageFeature",
"LineagePowerHint",
],
gen_java: true,
}

View file

@ -0,0 +1,27 @@
/*
* Copyright (C) 2018 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package vendor.lineage.power@1.0;
interface ILineagePower {
/**
* getFeature() is called to get the current value of a particular
* feature or capability from the hardware or PowerHAL
*
* @param feature Feature which needs to get
* @return the state of power states the device supports
*/
getFeature(LineageFeature feature) generates (int32_t value);
};

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 2018 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package vendor.lineage.power@1.0;
/** Power hint identifiers passed to powerHint() */
enum LineagePowerHint : uint32_t {
/**
* An operation is happening where it would be ideal for the CPU to
* be boosted for a specific duration. The data parameter is an
* integer value of the boost duration in microseconds.
*/
CPU_BOOST = 0x00000110,
SET_PROFILE = 0x00000111
};
enum LineageFeature : uint32_t {
SUPPORTED_PROFILES = 0x00001000
};

View file

@ -205,12 +205,12 @@
<hal format="hidl">
<name>android.hardware.power</name>
<transport>hwbinder</transport>
<version>1.0</version>
<version>1.2</version>
<interface>
<name>IPower</name>
<instance>default</instance>
</interface>
<fqname>@1.0::IPower/default</fqname>
<fqname>@1.2::IPower/default</fqname>
</hal>
<hal format="hidl">
<name>android.hardware.radio</name>

View file

@ -1,36 +1,92 @@
# Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
# Copyright (C) 2017-2019 The LineageOS Project
#
# 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.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_SHARED_LIBRARIES := \
liblog \
libcutils \
libdl \
libbase \
libhidlbase \
libhidltransport \
libhwbinder \
libutils \
android.hardware.power@1.2 \
vendor.lineage.power@1.0
LOCAL_HEADER_LIBRARIES := \
libhardware_headers
LOCAL_SRC_FILES := \
power-common.c \
metadata-parser.c \
utils.c \
list.c \
hint-data.c \
power-710.c \
service.cpp \
Power.cpp
LOCAL_CFLAGS += -Wall -Wextra -Werror
ifneq ($(BOARD_POWER_CUSTOM_BOARD_LIB),)
LOCAL_WHOLE_STATIC_LIBRARIES += $(BOARD_POWER_CUSTOM_BOARD_LIB)
else
ifneq ($(TARGET_POWER_SET_FEATURE_LIB),)
LOCAL_STATIC_LIBRARIES += $(TARGET_POWER_SET_FEATURE_LIB)
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
LOCAL_MODULE := power.qcom
LOCAL_MODULE_PATH_32 := $(TARGET_OUT_PRODUCT)/vendor_overlay/$(PRODUCT_TARGET_VNDK_VERSION)/lib
LOCAL_MODULE_PATH_64 := $(TARGET_OUT_PRODUCT)/vendor_overlay/$(PRODUCT_TARGET_VNDK_VERSION)/lib64
LOCAL_INIT_RC := android.hardware.power@1.0-service.rc
LOCAL_MODULE_RELATIVE_PATH := hw
ifeq ($(TARGET_USES_INTERACTION_BOOST),true)
LOCAL_CFLAGS += -DINTERACTION_BOOST
endif
ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -DARCH_ARM_32
endif
LOCAL_MODULE := android.hardware.power@1.2-service-qti
LOCAL_INIT_RC := android.hardware.power@1.2-service-qti.rc
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := \
hint-data.c \
list.c \
metadata-parser.c \
power-710.c \
power.c \
powerhintparser.c \
utils.c
LOCAL_C_INCLUDES := external/libxml2/include \
external/icu/icu4c/source/common
LOCAL_SHARED_LIBRARIES := liblog libcutils libdl libxml2
LOCAL_HEADER_LIBRARIES += libutils_headers
LOCAL_HEADER_LIBRARIES += libhardware_headers
LOCAL_CFLAGS += -Werror -Wall -Wno-unused-parameter
LOCAL_CFLAGS += -DINTERACTION_BOOST
include $(BUILD_SHARED_LIBRARY)
include $(BUILD_EXECUTABLE)
endif

32
power/NOTICE Normal file
View file

@ -0,0 +1,32 @@
Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the name of The Linux Foundation nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE
GRANTED BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

141
power/Power.cpp Normal file
View file

@ -0,0 +1,141 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2017-2019 The LineageOS Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LOG_TAG "android.hardware.power@1.2-service-qti"
// #define LOG_NDEBUG 0
#include "Power.h"
#include <android-base/file.h>
#include <log/log.h>
#include "power-common.h"
#include "power-feature.h"
namespace android {
namespace hardware {
namespace power {
namespace V1_2 {
namespace implementation {
using ::android::hardware::hidl_vec;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::power::V1_0::Feature;
using ::android::hardware::power::V1_0::PowerHint;
using ::android::hardware::power::V1_0::PowerStatePlatformSleepState;
using ::android::hardware::power::V1_0::Status;
using ::android::hardware::power::V1_1::PowerStateSubsystem;
Power::Power() {
power_init();
}
Return<void> Power::setInteractive(bool interactive) {
set_interactive(interactive ? 1 : 0);
return Void();
}
Return<void> Power::powerHint(PowerHint_1_0 hint, int32_t data) {
power_hint(static_cast<power_hint_t>(hint), data ? (&data) : NULL);
return Void();
}
Return<void> Power::setFeature(Feature feature, bool activate) {
switch (feature) {
#ifdef TAP_TO_WAKE_NODE
case Feature::POWER_FEATURE_DOUBLE_TAP_TO_WAKE:
::android::base::WriteStringToFile(activate ? "1" : "0", TAP_TO_WAKE_NODE, true);
break;
#endif
default:
break;
}
set_device_specific_feature(static_cast<feature_t>(feature), activate ? 1 : 0);
return Void();
}
Return<void> Power::getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) {
hidl_vec<PowerStatePlatformSleepState> states;
states.resize(0);
_hidl_cb(states, Status::SUCCESS);
return Void();
}
Return<void> Power::getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) {
hidl_vec<PowerStateSubsystem> subsystems;
_hidl_cb(subsystems, Status::SUCCESS);
return Void();
}
Return<void> Power::powerHintAsync(PowerHint_1_0 hint, int32_t data) {
return powerHint(hint, data);
}
Return<void> Power::powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) {
return powerHint(static_cast<PowerHint_1_0>(hint), data);
}
Return<int32_t> Power::getFeature(LineageFeature feature) {
if (feature == LineageFeature::SUPPORTED_PROFILES) {
return get_number_of_profiles();
}
return -1;
}
status_t Power::registerAsSystemService() {
status_t ret = 0;
ret = IPower::registerAsService();
if (ret != 0) {
ALOGE("Failed to register IPower (%d)", ret);
goto fail;
} else {
ALOGI("Successfully registered IPower");
}
ret = ILineagePower::registerAsService();
if (ret != 0) {
ALOGE("Failed to register ILineagePower (%d)", ret);
goto fail;
} else {
ALOGI("Successfully registered ILineagePower");
}
fail:
return ret;
}
} // namespace implementation
} // namespace V1_2
} // namespace power
} // namespace hardware
} // namespace android

82
power/Power.h Normal file
View file

@ -0,0 +1,82 @@
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2017-2019 The LineageOS Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
* * Neither the name of The Linux Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef ANDROID_HARDWARE_POWER_V1_2_POWER_H
#define ANDROID_HARDWARE_POWER_V1_2_POWER_H
#include <android/hardware/power/1.2/IPower.h>
#include <hardware/power.h>
#include <hidl/MQDescriptor.h>
#include <hidl/Status.h>
#include <vendor/lineage/power/1.0/ILineagePower.h>
namespace android {
namespace hardware {
namespace power {
namespace V1_2 {
namespace implementation {
using ::android::hardware::power::V1_0::Feature;
using PowerHint_1_0 = ::android::hardware::power::V1_0::PowerHint;
using PowerHint_1_2 = ::android::hardware::power::V1_2::PowerHint;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::power::V1_2::IPower;
using ::vendor::lineage::power::V1_0::ILineagePower;
using ::vendor::lineage::power::V1_0::LineageFeature;
struct Power : public IPower, public ILineagePower {
// Methods from ::android::hardware::power::V1_0::IPower follow.
Power();
status_t registerAsSystemService();
Return<void> setInteractive(bool interactive) override;
Return<void> powerHint(PowerHint_1_0 hint, int32_t data) override;
Return<void> setFeature(Feature feature, bool activate) override;
Return<void> getPlatformLowPowerStats(getPlatformLowPowerStats_cb _hidl_cb) override;
// Methods from ::android::hardware::power::V1_1::IPower follow
Return<void> getSubsystemLowPowerStats(getSubsystemLowPowerStats_cb _hidl_cb) override;
Return<void> powerHintAsync(PowerHint_1_0 hint, int32_t data) override;
// Methods from ::android::hardware::power::V1_2::IPower follow
Return<void> powerHintAsync_1_2(PowerHint_1_2 hint, int32_t data) override;
// Methods from ::vendor::lineage::power::V1_0::ILineagePower follow.
Return<int32_t> getFeature(LineageFeature feature) override;
};
} // namespace implementation
} // namespace V1_2
} // namespace power
} // namespace hardware
} // namespace android
#endif // ANDROID_HARDWARE_POWER_V1_2_POWER_H

View file

@ -1,5 +0,0 @@
service vendor.power-hal-1-0 /vendor/bin/hw/android.hardware.power@1.0-service
override
class hal
user system
group system input

View file

@ -0,0 +1,4 @@
service vendor.power-hal-1-2 /system/bin/hw/android.hardware.power@1.2-service-qti
class hal
user system
group system

View file

@ -27,7 +27,7 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <utils/Log.h>
#include <log/log.h>
#include "hint-data.h"
@ -42,5 +42,5 @@ int hint_compare(struct hint_data* first_hint, struct hint_data* other_hint) {
}
void hint_dump(struct hint_data* hint) {
ALOGI("hint_id: %lu", hint->hint_id);
ALOGV("hint_id: %lu", hint->hint_id);
}

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2012, 2013, 2015, 2017-2018, The Linux Foundation. All rights reserved.
* Copyright (C) 2018-2019 The LineageOS Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -36,7 +37,6 @@
#define SUSTAINED_PERF_HINT_ID (0x0F00)
#define VR_MODE_HINT_ID (0x1000)
#define VR_MODE_SUSTAINED_PERF_HINT_ID (0x1001)
#define INTERACTION_HINT_ID (0x1A00)
#define AOSP_DELTA (0x1200)
@ -50,12 +50,14 @@
#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)
struct hint_handles{
#define DEFAULT_PROFILE_HINT_ID (0xFF00)
struct hint_handles {
int handle;
int ref_count;
};

View file

@ -31,17 +31,9 @@
#include <stdlib.h>
#include <string.h>
#include <utils/Log.h>
#include <log/log.h>
#include "list.h"
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) {
/* Create a new list_node. And put 'data' into it. */
struct list_node* new_node;
@ -63,10 +55,6 @@ 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'.
*/
@ -102,20 +90,6 @@ 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;
ALOGV("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;

View file

@ -34,8 +34,6 @@ struct list_node {
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);

View file

@ -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
@ -41,20 +42,20 @@ extern "C" {
#define VENDOR_HINT_DISPLAY_OFF 0x00001040
#define VENDOR_HINT_DISPLAY_ON 0x00001041
#define VENDOR_HINT_FIRST_LAUNCH_BOOST 0x00001081
#define VENDOR_HINT_SCROLL_BOOST 0x00001080
#define VENDOR_HINT_FIRST_LAUNCH_BOOST 0x00001081
enum {
LAUNCH_BOOST_V1 = 1,
LAUNCH_BOOST_V2 = 2,
LAUNCH_BOOST_V3 = 3
};
enum {
enum SCROLL_BOOST_TYPE {
SCROLL_VERTICAL = 1,
SCROLL_HORIZONTAL = 2,
SCROLL_PANEL_VIEW = 3,
SCROLL_PREFILING = 4
SCROLL_PREFILING = 4,
};
enum LAUNCH_BOOST_TYPE {
LAUNCH_BOOST_V1 = 1,
LAUNCH_BOOST_V2 = 2,
LAUNCH_BOOST_V3 = 3,
};
enum SCREEN_DISPLAY_TYPE {
@ -140,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,
@ -200,6 +191,7 @@ enum INTERACTIVE_OPCODES {
enum INTERACTIVE_HISPEED_FREQ_LVL {
HS_FREQ_1026 = 0xF0A,
HS_FREQ_800 = 0xF08,
};
enum INTERACTIVE_HISPEED_LOAD_LVL {
@ -276,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

View file

@ -1,5 +1,4 @@
/*
* Copyright (c) 2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -27,8 +26,6 @@
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define LOG_NIDEBUG 0
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
@ -36,13 +33,12 @@
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <pthread.h>
#include <unistd.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
#include <hardware/power.h>
#include <utils/Log.h>
#include <log/log.h>
#include "hint-data.h"
#include "metadata-defs.h"
@ -50,242 +46,38 @@
#include "power-common.h"
#include "utils.h"
#define CHECK_HANDLE(x) ((x) > 0)
#define NUM_PERF_MODES 3
static int display_fd;
#define SYS_DISPLAY_PWR "/sys/kernel/hbtp/display_pwr"
const int kMaxLaunchDuration = 5000; /* ms */
const int kMaxInteractiveDuration = 5000; /* ms */
const int kMinInteractiveDuration = 100; /* ms */
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;
int rc = 0;
typedef enum {
NORMAL_MODE = 0,
SUSTAINED_MODE = 1,
VR_MODE = 2,
VR_SUSTAINED_MODE = (SUSTAINED_MODE | VR_MODE),
INVALID_MODE = 0xFF
} perf_mode_type_t;
typedef struct perf_mode {
perf_mode_type_t type;
int perf_hint_id;
} perf_mode_t;
perf_mode_t perf_modes[NUM_PERF_MODES] = {{SUSTAINED_MODE, SUSTAINED_PERF_HINT},
{VR_MODE, VR_MODE_HINT},
{VR_SUSTAINED_MODE, VR_MODE_SUSTAINED_PERF_HINT}};
static pthread_mutex_t perf_mode_switch_lock = PTHREAD_MUTEX_INITIALIZER;
static int current_mode = NORMAL_MODE;
static inline int get_perfd_hint_id(perf_mode_type_t type) {
int i;
for (i = 0; i < NUM_PERF_MODES; i++) {
if (perf_modes[i].type == type) {
ALOGD("Hint id is 0x%x for mode 0x%x", perf_modes[i].perf_hint_id, type);
return perf_modes[i].perf_hint_id;
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);
}
}
ALOGD("Couldn't find the hint for mode 0x%x", type);
return 0;
}
static int switch_mode(perf_mode_type_t mode) {
int hint_id = 0;
static int perfd_mode_handle = -1;
// release existing mode if any
if (CHECK_HANDLE(perfd_mode_handle)) {
ALOGD("Releasing handle 0x%x", perfd_mode_handle);
release_request(perfd_mode_handle);
perfd_mode_handle = -1;
}
// switch to a perf mode
hint_id = get_perfd_hint_id(mode);
if (hint_id != 0) {
perfd_mode_handle = perf_hint_enable(hint_id, 0);
if (!CHECK_HANDLE(perfd_mode_handle)) {
ALOGE("Failed perf_hint_interaction for mode: 0x%x", mode);
return -1;
}
ALOGD("Acquired handle 0x%x", perfd_mode_handle);
}
return 0;
}
static int process_perf_hint(void* data, perf_mode_type_t mode) {
pthread_mutex_lock(&perf_mode_switch_lock);
// enable
if (data) {
ALOGI("Enable request for mode: 0x%x", mode);
// check if mode is current mode
if (current_mode & mode) {
pthread_mutex_unlock(&perf_mode_switch_lock);
ALOGD("Mode 0x%x already enabled", mode);
return HINT_HANDLED;
}
// enable requested mode
if (0 != switch_mode(current_mode | mode)) {
pthread_mutex_unlock(&perf_mode_switch_lock);
ALOGE("Couldn't enable mode 0x%x", mode);
return HINT_NONE;
}
current_mode |= mode;
ALOGI("Current mode is 0x%x", current_mode);
// disable
} else {
ALOGI("Disable request for mode: 0x%x", mode);
// check if mode is enabled
if (!(current_mode & mode)) {
pthread_mutex_unlock(&perf_mode_switch_lock);
ALOGD("Mode 0x%x already disabled", mode);
return HINT_HANDLED;
/* 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);
}
// disable requested mode
if (0 != switch_mode(current_mode & ~mode)) {
pthread_mutex_unlock(&perf_mode_switch_lock);
ALOGE("Couldn't disable mode 0x%x", mode);
return HINT_NONE;
}
current_mode &= ~mode;
ALOGI("Current mode is 0x%x", current_mode);
}
pthread_mutex_unlock(&perf_mode_switch_lock);
return HINT_HANDLED;
}
static int process_video_encode_hint(void* metadata) {
char governor[80];
struct video_encode_metadata_t video_encode_metadata;
static int video_encode_handle = 0;
if (!metadata) return HINT_NONE;
if (get_scaling_governor(governor, sizeof(governor)) == -1) {
ALOGE("Can't obtain scaling governor.");
return HINT_NONE;
}
/* Initialize encode metadata struct fields */
memset(&video_encode_metadata, 0, sizeof(struct video_encode_metadata_t));
video_encode_metadata.state = -1;
if (parse_video_encode_metadata((char*)metadata, &video_encode_metadata) == -1) {
ALOGE("Error occurred while parsing metadata.");
return HINT_NONE;
}
if (video_encode_metadata.state == 1) {
if (is_interactive_governor(governor)) {
video_encode_handle = perf_hint_enable(VIDEO_ENCODE_HINT, 0);
ALOGI("Video encode hint start");
return HINT_HANDLED;
}
} else if (video_encode_metadata.state == 0) {
if (is_interactive_governor(governor)) {
release_request(video_encode_handle);
ALOGI("Video Encode hint stop");
return HINT_HANDLED;
}
}
return HINT_NONE;
}
static int process_activity_launch_hint(void* data) {
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;
}
static int process_interaction_hint(void* data) {
static struct timespec s_previous_boost_timespec;
static int s_previous_duration = 0;
struct timespec cur_boost_timespec;
long long elapsed_time;
int duration = kMinInteractiveDuration;
if (current_mode != NORMAL_MODE) {
ALOGV("%s: ignoring due to other active perf hints", __func__);
return HINT_HANDLED;
}
if (data) {
int input_duration = *((int*)data);
if (input_duration > duration) {
duration = (input_duration > kMaxInteractiveDuration) ?
kMaxInteractiveDuration : input_duration;
}
}
clock_gettime(CLOCK_MONOTONIC, &cur_boost_timespec);
elapsed_time = calc_timespan_us(s_previous_boost_timespec, cur_boost_timespec);
// don't hint if previous hint's duration covers this hint's duration
if ((s_previous_duration * 1000) > (elapsed_time + duration * 1000)) {
return HINT_HANDLED;
}
s_previous_boost_timespec = cur_boost_timespec;
s_previous_duration = duration;
perf_hint_enable_with_type(VENDOR_HINT_SCROLL_BOOST, duration, SCROLL_VERTICAL);
return HINT_HANDLED;
}
int power_hint_override(struct power_module* module, power_hint_t hint, void* data) {
int ret_val = HINT_NONE;
switch (hint) {
case POWER_HINT_VIDEO_ENCODE:
ret_val = process_video_encode_hint(data);
break;
case POWER_HINT_SUSTAINED_PERFORMANCE:
ret_val = process_perf_hint(data, SUSTAINED_MODE);
break;
case POWER_HINT_VR_MODE:
ret_val = process_perf_hint(data, VR_MODE);
break;
case POWER_HINT_INTERACTION:
ret_val = process_interaction_hint(data);
break;
case POWER_HINT_LAUNCH:
ret_val = process_activity_launch_hint(data);
break;
default:
break;
}
return ret_val;
}
int set_interactive_override(struct power_module* module, int on) {
static int set_i_count = 0;
set_i_count++;
ALOGI("Got set_interactive hint on= %d, count= %d\n", on, set_i_count);
return HINT_HANDLED; /* Don't excecute this code path, not in use */
}

148
power/power-common.c Normal file
View file

@ -0,0 +1,148 @@
/*
* Copyright (c) 2012-2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2017-2019 The LineageOS Project
*
* 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 <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define LOG_TAG "QTI PowerHAL"
#include <hardware/hardware.h>
#include <hardware/power.h>
#include <log/log.h>
#include "hint-data.h"
#include "performance.h"
#include "power-common.h"
#include "power-feature.h"
#include "utils.h"
static struct hint_handles handles[NUM_HINTS];
void power_init() {
ALOGI("Initing");
for (int i = 0; i < NUM_HINTS; i++) {
handles[i].handle = 0;
handles[i].ref_count = 0;
}
}
int __attribute__((weak)) power_hint_override(power_hint_t UNUSED(hint), void* UNUSED(data)) {
return HINT_NONE;
}
void power_hint(power_hint_t hint, void* data) {
/* Check if this hint has been overridden. */
if (power_hint_override(hint, data) == HINT_HANDLED) {
/* The power_hint has been handled. We can skip the rest. */
return;
}
switch (hint) {
case POWER_HINT_VR_MODE:
ALOGI("VR mode power hint not handled in power_hint_override");
break;
// fall through below, hints will fail if not defined in powerhint.xml
case POWER_HINT_SUSTAINED_PERFORMANCE:
case POWER_HINT_VIDEO_ENCODE:
if (data) {
if (handles[hint].ref_count == 0)
handles[hint].handle = perf_hint_enable((AOSP_DELTA + hint), 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 {
ALOGE("Lock for hint: %X was not acquired, cannot be released", hint);
}
}
break;
case POWER_HINT_SET_PROFILE:
ALOGI("set profile power hint not handled in power_hint_override");
break;
default:
break;
}
}
int __attribute__((weak)) get_number_of_profiles() {
return 0;
}
int __attribute__((weak)) set_interactive_override(int UNUSED(on)) {
return HINT_NONE;
}
#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);
} else {
/* Send Display ON hint to perf HAL */
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");
}
}
void __attribute__((weak))
set_device_specific_feature(feature_t UNUSED(feature), int UNUSED(state)) {}

View file

@ -1,5 +1,6 @@
/*
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
* Copyright (c) 2013, 2018-2019 The Linux Foundation. All rights reserved.
* Copyright (C) 2017-2019 The LineageOS Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -26,19 +27,45 @@
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#define NODE_MAX (64)
#ifndef __POWER_COMMON_H__
#define __POWER_COMMON_H__
#ifdef __cplusplus
extern "C" {
#endif
#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)
#define HINT_NONE (-1)
#include <hardware/power.h>
enum CPU_GOV_CHECK { CPU0 = 0, CPU1 = 1, CPU2 = 2, CPU3 = 3 };
enum {
PROFILE_POWER_SAVE = 0,
PROFILE_BALANCED,
PROFILE_HIGH_PERFORMANCE,
PROFILE_BIAS_POWER,
PROFILE_BIAS_PERFORMANCE
};
void power_init(void);
void power_hint(power_hint_t hint, void* data);
void set_interactive(int on);
int get_number_of_profiles();
#define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#define CHECK_HANDLE(x) ((x) > 0)
#define UNUSED(x) UNUSED_##x __attribute__((__unused__))
// Custom Lineage hints
const static power_hint_t POWER_HINT_SET_PROFILE = (power_hint_t)0x00000111;
#ifdef __cplusplus
}
#endif
#endif //__POWER_COMMON_H___

33
power/power-feature.h Normal file
View file

@ -0,0 +1,33 @@
/*
* Copyright (C) 2015 The CyanogenMod Project
* Copyright (C) 2019 The LineageOS Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _QCOM_POWER_FEATURE_H
#define _QCOM_POWER_FEATURE_H
#include <hardware/power.h>
#ifdef __cplusplus
extern "C" {
#endif
void set_device_specific_feature(feature_t feature, int state);
#ifdef __cplusplus
}
#endif
#endif

View file

@ -1,203 +0,0 @@
/*
* Copyright (c) 2012-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 <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#define LOG_TAG "QCOM PowerHAL"
#include <hardware/hardware.h>
#include <hardware/power.h>
#include <utils/Log.h>
#include "hint-data.h"
#include "performance.h"
#include "power-common.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 struct hw_module_methods_t power_module_methods = {
.open = power_device_open,
};
static void power_init(struct power_module* module) {
ALOGI("Initing");
for (int i = 0; i < NUM_HINTS; i++) {
handles[i].handle = 0;
handles[i].ref_count = 0;
}
}
int __attribute__((weak))
power_hint_override(struct power_module* module, power_hint_t hint, void* data) {
return HINT_NONE;
}
/* Declare function before use */
void interaction(int duration, int num_args, int opt_list[]);
static void power_hint(struct power_module* module, power_hint_t hint, void* data) {
/* Check if this hint has been overridden. */
if (power_hint_override(module, hint, data) == HINT_HANDLED) {
/* The power_hint has been handled. We can skip the rest. */
return;
}
switch (hint) {
case POWER_HINT_VSYNC:
break;
case POWER_HINT_VR_MODE:
ALOGI("VR mode power hint not handled in power_hint_override");
break;
case POWER_HINT_INTERACTION: {
int resources[] = {0x702, 0x20F, 0x30F};
int duration = 3000;
interaction(duration, sizeof(resources) / sizeof(resources[0]), resources);
} break;
//fall through below, hints will fail if not defined in powerhint.xml
case POWER_HINT_SUSTAINED_PERFORMANCE:
case POWER_HINT_VIDEO_ENCODE:
if (data) {
if (handles[hint].ref_count == 0)
handles[hint].handle = perf_hint_enable((AOSP_DELTA + hint), 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 {
ALOGE("Lock for hint: %X was not acquired, cannot be released", hint);
}
}
break;
default:
break;
}
}
int __attribute__((weak)) set_interactive_override(struct power_module* module, int on) {
return HINT_NONE;
}
void set_interactive(struct power_module* module, int on) {
if (!on) {
/* Send Display OFF hint to perf HAL */
perf_hint_enable(VENDOR_HINT_DISPLAY_OFF, 0);
} else {
/* Send Display ON hint to perf HAL */
perf_hint_enable(VENDOR_HINT_DISPLAY_ON, 0);
}
if (set_interactive_override(module, on) == HINT_HANDLED) {
return;
}
ALOGI("Got set_interactive hint");
}
void set_feature(struct power_module* module, feature_t feature, int state) {
switch (feature) {
#ifdef TAP_TO_WAKE_NODE
case POWER_FEATURE_DOUBLE_TAP_TO_WAKE:
sysfs_write(TAP_TO_WAKE_NODE, state ? "1" : "0");
break;
#endif
default:
break;
}
}
static int power_device_open(const hw_module_t* module, const char* name, hw_device_t** device) {
int status = -EINVAL;
if (module && name && device) {
if (!strcmp(name, POWER_HARDWARE_MODULE_ID)) {
power_module_t* dev = (power_module_t*)malloc(sizeof(*dev));
if (dev) {
memset(dev, 0, sizeof(*dev));
if (dev) {
/* initialize the fields */
dev->common.module_api_version = POWER_MODULE_API_VERSION_0_3;
dev->common.tag = HARDWARE_DEVICE_TAG;
dev->init = power_init;
dev->powerHint = power_hint;
dev->setInteractive = set_interactive;
/* At the moment we support 0.3 APIs */
dev->setFeature = set_feature;
dev->get_number_of_platform_modes = NULL;
dev->get_platform_low_power_stats = NULL;
dev->get_voter_list = NULL;
*device = (hw_device_t*)dev;
status = 0;
} else {
status = -ENOMEM;
}
} else {
status = -ENOMEM;
}
}
}
return status;
}
struct power_module HAL_MODULE_INFO_SYM = {
.common =
{
.tag = HARDWARE_MODULE_TAG,
.module_api_version = POWER_MODULE_API_VERSION_0_3,
.hal_api_version = HARDWARE_HAL_API_VERSION,
.id = POWER_HARDWARE_MODULE_ID,
.name = "QCOM Power HAL",
.author = "Qualcomm",
.methods = &power_module_methods,
},
.init = power_init,
.powerHint = power_hint,
.setInteractive = set_interactive,
.setFeature = set_feature
};

View file

@ -1,172 +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.
*
*/
#define LOG_TAG "QCOM PowerHAL"
#include "powerhintparser.h"
#include <cutils/log.h>
#include <cutils/properties.h>
#include <fcntl.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <string.h>
#include <unistd.h>
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;
}

View file

@ -1,4 +1,6 @@
/* Copyright (c) 2016, The Linux Foundation. All rights reserved.
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
* Copyright (C) 2017-2019 The LineageOS Project
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@ -24,25 +26,63 @@
* 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 LOG_TAG "android.hardware.power@1.2-service-qti"
#define POWERHINT_XML "/vendor/etc/powerhint.xml"
#define MAX_HINT 6
#define MAX_PARAM 30
// #define LOG_NDEBUG 0
typedef struct perflock_param_t {
int type;
int numParams;
int paramList[MAX_PARAM]; // static limit on number of hints - 15
} perflock_param_t;
#include <hardware/power.h>
#include <hidl/HidlTransportSupport.h>
#ifdef ARCH_ARM_32
#include <hwbinder/ProcessState.h>
#endif
#include <log/log.h>
#include "Power.h"
static perflock_param_t powerhint[MAX_HINT];
using android::OK;
using android::sp;
using android::status_t;
int parsePowerhintXML();
int* getPowerhint(int, int*);
// libhwbinder:
using android::hardware::configureRpcThreadpool;
using android::hardware::joinRpcThreadpool;
#endif /* __POWERHINTPARSER__ */
// Generated HIDL files
using android::hardware::power::V1_2::implementation::Power;
int main() {
#ifdef ARCH_ARM_32
android::hardware::ProcessState::initWithMmapSize((size_t)16384);
#endif
status_t status;
android::sp<Power> service = nullptr;
ALOGI("Power HAL Service 1.2 is starting.");
service = new Power();
if (service == nullptr) {
ALOGE("Can not create an instance of Power HAL interface.");
goto shutdown;
}
configureRpcThreadpool(1, true /*callerWillJoin*/);
status = service->registerAsSystemService();
if (status != OK) {
ALOGE("Could not register service for Power HAL(%d).", status);
goto shutdown;
}
ALOGI("Power Service is ready");
joinRpcThreadpool();
// Should not pass this line
shutdown:
// In normal operation, we don't expect the thread pool to exit
ALOGE("Power Service is shutting down");
return 1;
}

View file

@ -40,32 +40,49 @@
#include "power-common.h"
#include "utils.h"
#define LOG_TAG "QCOM PowerHAL"
#include <utils/Log.h>
#define LOG_TAG "QTI PowerHAL"
#include <log/log.h>
#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)(unsigned long handle, int duration, int list[], int numArgs);
static int (*perf_lock_rel)(unsigned long handle);
static int (*perf_hint)(int, char*, int, int);
static int (*perf_lock_acq)(int handle, int duration, int list[], int numArgs);
static int (*perf_lock_rel)(int handle);
static int (*perf_hint)(int, const char*, int, int);
static struct list_node active_hint_list_head;
const char* pkg = "QTI PowerHAL";
static void* get_qcopt_handle() {
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;
@ -107,7 +124,7 @@ static void __attribute__((destructor)) cleanup(void) {
}
}
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;
@ -134,7 +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;
@ -160,19 +177,14 @@ int sysfs_write(char* path, char* s) {
}
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';
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) {
@ -194,8 +206,15 @@ int is_interactive_governor(char* governor) {
return 0;
}
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 UNUSED(duration), int UNUSED(num_args), int UNUSED(opt_list[])) {
#else
void interaction(int duration, int num_args, int opt_list[]) {
#ifdef INTERACTION_BOOST
static int lock_handle = 0;
if (duration < 0 || num_args < 1 || opt_list[0] == 0) return;
@ -230,15 +249,15 @@ int perf_hint_enable(int hint_id, int duration) {
if (qcopt_handle) {
if (perf_hint) {
lock_handle = perf_hint(hint_id, NULL, duration, -1);
if (lock_handle == -1)
ALOGE("Failed to acquire lock for hint_id: %X.", hint_id);
lock_handle = perf_hint(hint_id, pkg, duration, -1);
if (lock_handle == -1) ALOGE("Failed to acquire lock for hint_id: %X.", hint_id);
}
}
return lock_handle;
}
// same as perf_hint_enable, but with the ability to choose the type
// 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;
@ -255,43 +274,43 @@ void release_request(int 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 (lock_handle == -1) {
ALOGE("Failed to acquire lock.");
return -EINVAL;
}
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;
}
/* Add this handle to our internal hint-list. */
struct hint_data* new_hint = (struct hint_data*)malloc(sizeof(struct hint_data));
new_hint->hint_id = hint_id;
new_hint->perflock_handle = lock_handle;
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 (add_list_node(&active_hint_list_head, new_hint) == NULL) {
free(new_hint);
/* Can't keep track of this lock. Release it. */
if (perf_lock_rel) perf_lock_rel(lock_handle);
if (!active_hint_list_head.compare) {
active_hint_list_head.compare = (int (*)(void*, void*))hint_compare;
active_hint_list_head.dump = (void (*)(void*))hint_dump;
}
ALOGE("Failed to process hint.");
}
} else {
/* Can't keep track of this lock. Release it. */
if (perf_lock_rel) perf_lock_rel(lock_handle);
new_hint->hint_id = hint_id;
new_hint->perflock_handle = lock_handle;
ALOGE("Failed to process hint.");
}
}
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) {
@ -337,6 +356,27 @@ void undo_initial_hint_action() {
}
}
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;

View file

@ -29,21 +29,21 @@
#include <cutils/properties.h>
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 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);

View file

@ -84,3 +84,6 @@ on post-fs-data
service face_hal /system/bin/true
disabled
service vendor.power-hal-1-0 /system/bin/true
disabled

View file

@ -104,7 +104,7 @@ PRODUCT_COPY_FILES += \
# Power
PRODUCT_PACKAGES += \
power.qcom:64
android.hardware.power@1.2-service-qti
# QTI Performance
PRODUCT_BOOT_JARS += \

View file

@ -6,6 +6,7 @@
# HALs
/system/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service\.realme_sdm710 u:object_r:hal_fingerprint_sdm710_exec:s0
/system/bin/hw/android\.hardware\.power@1\.2-service-qti u:object_r:hal_power_default_exec:s0
/(product|system/product)/vendor_overlay/[0-9]+/bin/hw/android\.hardware\.light@2\.0-service u:object_r:hal_light_default_exec:s0
/(product|system/product)/vendor_overlay/[0-9]+/bin/hw/android\.hardware\.usb@1\.0-service u:object_r:hal_usb_default_exec:s0