update power hal to fix vibration issue and enable all cores at start

This commit is contained in:
PythonLimited 2019-01-15 00:47:25 +01:00
parent 38495501f8
commit 26dd0b136d
10 changed files with 442 additions and 177 deletions

View file

@ -1,3 +0,0 @@
# Power HAL
TARGET_POWERHAL_SET_INTERACTIVE_EXT := $(VENDOR_PATH)/power/power_ext.c
TARGET_POWERHAL_VARIANT := qcom

26
power/Android.mk Normal file
View file

@ -0,0 +1,26 @@
#
# Copyright 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.
#
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(TARGET_POWERHAL_HEADER_PATH)
LOCAL_SRC_FILES := power.c
LOCAL_SHARED_LIBRARIES := liblog libcutils
LOCAL_MODULE_RELATIVE_PATH := hw
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := power.msm8226
LOCAL_PROPRIETARY_MODULE := true
include $(BUILD_SHARED_LIBRARY)

275
power/power.c Normal file
View file

@ -0,0 +1,275 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define LOG_TAG "PowerHAL"
#include <hardware/hardware.h>
#include <hardware/power.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdlib.h>
#include <utils/Log.h>
#include "power.h"
#define CPUFREQ_PATH "/sys/devices/system/cpu/cpu0/cpufreq/"
#define INTERACTIVE_PATH "/sys/devices/system/cpu/cpufreq/interactive/"
/* touchkeys */
#define TK_POWER "/sys/class/input/input1/enabled"
/* touchscreen */
#define TS_POWER "/sys/class/input/input2/enabled"
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static int boostpulse_fd = -1;
static int current_power_profile = -1;
static int requested_power_profile = -1;
static int sysfs_write_str(char *path, char *s)
{
char buf[80];
int len;
int ret = 0;
int fd;
fd = open(path, O_WRONLY);
if (fd < 0) {
strerror_r(errno, buf, sizeof(buf));
ALOGE("Error opening %s: %s\n", path, buf);
return -1 ;
}
len = write(fd, s, strlen(s));
if (len < 0) {
strerror_r(errno, buf, sizeof(buf));
ALOGE("Error writing to %s: %s\n", path, buf);
ret = -1;
}
close(fd);
return ret;
}
static int sysfs_write_int(char *path, int value)
{
char buf[80];
snprintf(buf, 80, "%d", value);
return sysfs_write_str(path, buf);
}
static int is_profile_valid(int profile)
{
return profile >= 0 && profile < PROFILE_MAX;
}
static void power_init(__attribute__((unused)) struct power_module *module)
{
ALOGI("%s", __func__);
}
static int boostpulse_open()
{
pthread_mutex_lock(&lock);
if (boostpulse_fd < 0) {
boostpulse_fd = open(INTERACTIVE_PATH "boostpulse", O_WRONLY);
}
pthread_mutex_unlock(&lock);
return boostpulse_fd;
}
static void power_set_interactive_ext(int on) {
ALOGD("%s: %s input devices", __func__, on ? "enabling" : "disabling");
sysfs_write_str(TK_POWER, on ? "1" : "0");
sysfs_write_str(TS_POWER, on ? "1" : "0");
}
static void power_set_interactive(__attribute__((unused)) struct power_module *module, int on)
{
if (!is_profile_valid(current_power_profile)) {
ALOGD("%s: no power profile selected yet", __func__);
return;
}
power_set_interactive_ext(on);
if (on) {
sysfs_write_int(INTERACTIVE_PATH "hispeed_freq",
profiles[current_power_profile].hispeed_freq);
sysfs_write_int(INTERACTIVE_PATH "go_hispeed_load",
profiles[current_power_profile].go_hispeed_load);
sysfs_write_int(INTERACTIVE_PATH "target_loads",
profiles[current_power_profile].target_loads);
sysfs_write_int(CPUFREQ_PATH "scaling_min_freq",
profiles[current_power_profile].scaling_min_freq);
} else {
sysfs_write_int(INTERACTIVE_PATH "hispeed_freq",
profiles[current_power_profile].hispeed_freq_off);
sysfs_write_int(INTERACTIVE_PATH "go_hispeed_load",
profiles[current_power_profile].go_hispeed_load_off);
sysfs_write_int(INTERACTIVE_PATH "target_loads",
profiles[current_power_profile].target_loads_off);
sysfs_write_int(CPUFREQ_PATH "scaling_min_freq",
profiles[current_power_profile].scaling_min_freq_off);
}
}
static void set_power_profile(int profile)
{
if (!is_profile_valid(profile)) {
ALOGE("%s: unknown profile: %d", __func__, profile);
return;
}
if (profile == current_power_profile)
return;
ALOGD("%s: setting profile %d", __func__, profile);
sysfs_write_int(INTERACTIVE_PATH "boost",
profiles[profile].boost);
sysfs_write_int(INTERACTIVE_PATH "boostpulse_duration",
profiles[profile].boostpulse_duration);
sysfs_write_int(INTERACTIVE_PATH "go_hispeed_load",
profiles[profile].go_hispeed_load);
sysfs_write_int(INTERACTIVE_PATH "hispeed_freq",
profiles[profile].hispeed_freq);
sysfs_write_int(INTERACTIVE_PATH "min_sample_time",
profiles[profile].min_sample_time);
sysfs_write_int(INTERACTIVE_PATH "timer_rate",
profiles[profile].timer_rate);
sysfs_write_int(INTERACTIVE_PATH "above_hispeed_delay",
profiles[profile].above_hispeed_delay);
sysfs_write_int(INTERACTIVE_PATH "target_loads",
profiles[profile].target_loads);
sysfs_write_int(CPUFREQ_PATH "scaling_max_freq",
profiles[profile].scaling_max_freq);
sysfs_write_int(CPUFREQ_PATH "scaling_min_freq",
profiles[profile].scaling_min_freq);
current_power_profile = profile;
}
static void power_hint(__attribute__((unused)) struct power_module *module,
power_hint_t hint, void *data)
{
char buf[80];
int len;
switch (hint) {
case POWER_HINT_INTERACTION:
if (!is_profile_valid(current_power_profile)) {
ALOGD("%s: no power profile selected yet", __func__);
return;
}
if (!profiles[current_power_profile].boostpulse_duration)
return;
if (boostpulse_open() >= 0) {
snprintf(buf, sizeof(buf), "%d", 1);
len = write(boostpulse_fd, &buf, sizeof(buf));
if (len < 0) {
strerror_r(errno, buf, sizeof(buf));
ALOGE("Error writing to boostpulse: %s\n", buf);
pthread_mutex_lock(&lock);
close(boostpulse_fd);
boostpulse_fd = -1;
pthread_mutex_unlock(&lock);
}
}
break;
case POWER_HINT_SET_PROFILE:
pthread_mutex_lock(&lock);
set_power_profile(*(int32_t *)data);
pthread_mutex_unlock(&lock);
break;
case POWER_HINT_LOW_POWER:
/* This hint is handled by the framework */
break;
default:
break;
}
}
static int get_feature(__attribute__((unused)) struct power_module *module,
feature_t feature)
{
if (feature == POWER_FEATURE_SUPPORTED_PROFILES) {
return PROFILE_MAX;
}
return -1;
}
static int power_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
ALOGD("%s: enter; name=%s", __FUNCTION__, name);
if (strcmp(name, POWER_HARDWARE_MODULE_ID)) {
return -EINVAL;
}
power_module_t *dev = (power_module_t *)calloc(1,
sizeof(power_module_t));
if (!dev) {
ALOGD("%s: failed to allocate memory", __FUNCTION__);
return -ENOMEM;
}
dev->common.tag = HARDWARE_MODULE_TAG;
dev->common.module_api_version = POWER_MODULE_API_VERSION_0_2;
dev->common.hal_api_version = HARDWARE_HAL_API_VERSION;
dev->init = power_init;
dev->powerHint = power_hint; // This is handled by framework
dev->setInteractive = power_set_interactive;
dev->getFeature = get_feature;
*device = (hw_device_t*)dev;
ALOGD("%s: exit", __FUNCTION__);
return 0;
}
static struct hw_module_methods_t power_module_methods = {
.open = power_open,
};
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 = "msm8226 Power HAL",
.author = "The LineageOS Project",
.methods = &power_module_methods,
},
.init = power_init,
.setInteractive = power_set_interactive,
.powerHint = power_hint,
.getFeature = get_feature
};

110
power/power.h Normal file
View file

@ -0,0 +1,110 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
enum {
PROFILE_POWER_SAVE = 0,
PROFILE_BALANCED,
PROFILE_HIGH_PERFORMANCE,
PROFILE_BIAS_POWER_SAVE,
PROFILE_MAX
};
typedef struct governor_settings {
int is_interactive;
int boost;
int boostpulse_duration;
int go_hispeed_load;
int go_hispeed_load_off;
int hispeed_freq;
int hispeed_freq_off;
int min_sample_time;
int timer_rate;
int above_hispeed_delay;
int target_loads;
int target_loads_off;
int scaling_max_freq;
int scaling_min_freq;
int scaling_min_freq_off;
} power_profile;
static power_profile profiles[PROFILE_MAX] = {
[PROFILE_POWER_SAVE] = {
.boost = 0,
.boostpulse_duration = 0,
.go_hispeed_load = 90,
.go_hispeed_load_off = 90,
.hispeed_freq = 787200,
.hispeed_freq_off = 787200,
.min_sample_time = 60000,
.timer_rate = 20000,
.above_hispeed_delay = 20000,
.target_loads = 90,
.target_loads_off = 90,
.scaling_max_freq = 998400,
.scaling_min_freq = 384000,
.scaling_min_freq_off = 300000,
},
[PROFILE_BALANCED] = {
.boost = 0,
.boostpulse_duration = 60000,
.go_hispeed_load = 80,
.go_hispeed_load_off = 90,
.hispeed_freq = 998400,
.hispeed_freq_off = 787200,
.min_sample_time = 60000,
.timer_rate = 20000,
.above_hispeed_delay = 20000,
.target_loads = 80,
.target_loads_off = 90,
.scaling_max_freq = 1401600,
.scaling_min_freq = 787200,
.scaling_min_freq_off = 300000,
},
[PROFILE_HIGH_PERFORMANCE] = {
.boost = 1,
/* The CPU is already boosted, set duration to zero
* to avoid unneccessary writes to boostpulse */
.boostpulse_duration = 0,
.go_hispeed_load = 60,
.go_hispeed_load_off = 70,
.hispeed_freq = 998400,
.hispeed_freq_off = 998400,
.min_sample_time = 60000,
.timer_rate = 20000,
.above_hispeed_delay = 20000,
.target_loads = 60,
.target_loads_off = 70,
.scaling_max_freq = 1401600,
.scaling_min_freq = 787200,
.scaling_min_freq_off = 300000,
},
[PROFILE_BIAS_POWER_SAVE] = {
.boost = 0,
.boostpulse_duration = 40000,
.go_hispeed_load = 90,
.go_hispeed_load_off = 90,
.hispeed_freq = 787200,
.hispeed_freq_off = 787200,
.min_sample_time = 60000,
.timer_rate = 20000,
.above_hispeed_delay = 20000,
.target_loads = 90,
.target_loads_off = 90,
.scaling_max_freq = 1190400,
.scaling_min_freq = 384000,
.scaling_min_freq_off = 300000,
},
};

View file

@ -1,58 +0,0 @@
/*
* Copyright (c) 2014 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <errno.h>
#include <string.h>
#include <fcntl.h>
#define LOG_TAG "PowerHAL_K_Ext"
#include <utils/Log.h>
/* touchkeys */
#define TK_POWER "/sys/class/input/input1/enabled"
/* touchscreen */
#define TS_POWER "/sys/class/input/input2/enabled"
static void sysfs_write(char *path, char *s) {
char buf[80];
int len;
int fd = open(path, O_WRONLY);
if (fd < 0) {
strerror_r(errno, buf, sizeof(buf));
ALOGE("Error opening %s: %s\n", path, buf);
return;
}
len = write(fd, s, strlen(s));
if (len < 0) {
strerror_r(errno, buf, sizeof(buf));
ALOGE("Error writing to %s: %s\n", path, buf);
}
close(fd);
}
void power_set_interactive_ext(int on) {
ALOGD("%s: %s input devices", __func__, on ? "enabling" : "disabling");
sysfs_write(TK_POWER, on ? "1" : "0");
sysfs_write(TS_POWER, on ? "1" : "0");
}
void cm_power_set_interactive_ext(int on) {
power_set_interactive_ext(on);
}

View file

@ -516,6 +516,37 @@ on boot
on property:sys.boot_completed=1
# Configure the CPU governor
write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor interactive
write /sys/devices/system/cpu/cpu1/cpufreq/scaling_governor interactive
write /sys/devices/system/cpu/cpu2/cpufreq/scaling_governor interactive
write /sys/devices/system/cpu/cpu3/cpufreq/scaling_governor interactive
write /sys/devices/system/cpu/cpufreq/interactive/above_hispeed_delay 20000
write /sys/devices/system/cpu/cpufreq/interactive/go_hispeed_load 99
write /sys/devices/system/cpu/cpufreq/interactive/hispeed_freq 998400
# Disable all hotplugs
write /sys/module/intelli_plug/parameters/intelli_plug_active 0
write /sys/module/intelli_plug/parameters/touch_boost_active 0
write /sys/module/cpu_boost/parameters/input_boost_ms 0
write /sys/module/msm_hotplug/msm_enabled 0
# we dont need M(ake)P(oor)decision
stop mpdecision
# Bring all CPUs online, and set node permissions AFTER disabling hotplugs otherwise
# only 1 core will be active
write /sys/devices/system/cpu/cpu1/online 1
write /sys/devices/system/cpu/cpu2/online 1
write /sys/devices/system/cpu/cpu3/online 1
chmod 664 /sys/devices/system/cpu/cpu1/online
chmod 664 /sys/devices/system/cpu/cpu2/online
chmod 664 /sys/devices/system/cpu/cpu3/online
chown root system /sys/devices/system/cpu/cpu1/online
chown root system /sys/devices/system/cpu/cpu2/online
chown root system /sys/devices/system/cpu/cpu3/online
# Symlink directories to access telephony.db and preferred-apn.xml required by libsec-ril
symlink /data/user_de/0/com.android.providers.telephony/databases /data/data/com.android.providers.telephony/databases
symlink /data/user_de/0/com.android.providers.telephony/shared_prefs /data/data/com.android.providers.telephony/shared_prefs
@ -578,11 +609,6 @@ service ril-daemon0 /vendor/bin/hw/rild
capabilities BLOCK_SUSPEND NET_ADMIN NET_RAW
disabled
service mpdecision /system/bin/mpdecision --avg_comp
class main
user root
oneshot
service qcamerasvr /system/bin/mm-qcamera-daemon
class late_start
user camera
@ -663,11 +689,6 @@ service wpa_supplicant /vendor/bin/hw/wpa_supplicant \
disabled
oneshot
on property:sys.boot_completed=1
# Symlink directories to access telephony.db and preferred-apn.xml required by libsec-ril
symlink /data/user_de/0/com.android.providers.telephony/databases /data/data/com.android.providers.telephony/databases
symlink /data/user_de/0/com.android.providers.telephony/shared_prefs /data/data/com.android.providers.telephony/shared_prefs
on property:init.svc.wpa_supplicant=stopped
stop dhcpcd

View file

@ -1,20 +0,0 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := wvm_shim.cpp
LOCAL_SHARED_LIBRARIES := libstagefright_foundation liblog libmedia libcutils
LOCAL_MODULE := libwvm_shim
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := imx175_shim.cpp
LOCAL_MODULE := libimx175_shim
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := sec-ril_shim.cpp
LOCAL_MODULE := sec-ril_shim
LOCAL_SHARED_LIBRARIES := liblog
LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)

View file

@ -1,17 +0,0 @@
#include <cutils/log.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <string.h>
extern "C" {
int property_get(const char * key, char * value, const char * default_value) {
ALOGE("%s: E", __FUNCTION__);
if (strcmp("ro.revision", key) == 0) {
ALOGE("%s: ro.revision was called!", __FUNCTION__);
strcpy(value, "4");
return 3;
}
ALOGE("%s: called other property: %s", __FUNCTION__, key);
return ((int( * )(const char * , char *, const char * ))(dlsym((void * ) - 1, "property_get")))(key, value, default_value);
}
}

View file

@ -1,11 +0,0 @@
#include <cutils/log.h>
#include <sys/types.h>
#include <dlfcn.h>
#include <string.h>
extern "C" {
int pcap_wrah(void) {
ALOGE("%s: pcap_wrap() called!\n", __func__);
return 0;
}
}

View file

@ -1,58 +0,0 @@
/*
* Copyright (C) 2016 The CyanogenMod Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <stdlib.h>
#include <stdint.h>
#include <media/IMediaSource.h>
#include <cutils/log.h>
#include <string.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaSource.h>
/* MediaBufferGroup::MediaBufferGroup */
//extern "C" int _ZN7android16MediaBufferGroupC1Ej(unsigned int);
//extern "C" int _ZN7android16MediaBufferGroupC1Ev() {
// return _ZN7android16MediaBufferGroupC1Ej(0);
//}
extern android::MediaBufferGroup* _ZN7android16MediaBufferGroupC1Ev() {
#ifdef AOSP
return new android::MediaBufferGroup();
#else
return new android::MediaBufferGroup(0);
#endif
}
extern int _ZN7android16MediaBufferGroup14acquire_bufferEPPNS_11MediaBufferEb(void *obj,android::MediaBuffer **out,
bool nonBlocking, size_t requestedSize) {
android::MediaBufferGroup *mbg = static_cast<android::MediaBufferGroup *>(obj);
return mbg->acquire_buffer(out,nonBlocking,requestedSize);
}
extern "C" {
// getSeekTo(int64_t *time_us, SeekMode *mode)
void _ZNK7android12IMediaSource11ReadOptions9getSeekToEPxPNS1_8SeekModeE(int64_t*, int32_t*);
// bool getNonBlocking()
bool _ZNK7android12IMediaSource11ReadOptions14getNonBlockingEv();
void _ZNK7android11MediaSource11ReadOptions9getSeekToEPxPNS1_8SeekModeE(int64_t *time_us, int32_t *mode) {
_ZNK7android12IMediaSource11ReadOptions9getSeekToEPxPNS1_8SeekModeE(time_us, mode);
}
bool _ZNK7android11MediaSource11ReadOptions14getNonBlockingEv() {
return _ZNK7android12IMediaSource11ReadOptions14getNonBlockingEv();
}
}