Add my own power driver and my own power management which is way more efficient and doesn't require crappy Allwinner stuff
This commit is contained in:
parent
5e844cf431
commit
9a1dc5701c
8 changed files with 358 additions and 7 deletions
|
@ -107,6 +107,7 @@ service iprenew_bt-pan /system/bin/dhcpcd -n
|
|||
service sayeye /system/bin/sayeye
|
||||
class core
|
||||
seclabel u:r:healthd:s0
|
||||
disabled
|
||||
user system
|
||||
group system
|
||||
socket sayeye stream 0660 root system
|
||||
|
|
|
@ -10,6 +10,9 @@ TARGET_NO_BOOTLOADER := true
|
|||
TARGET_NO_RECOVERY := false
|
||||
TARGET_NO_KERNEL := false
|
||||
|
||||
ENABLE_CPUSETS := true
|
||||
# ENABLE_SCHED_BOOST := true
|
||||
|
||||
POLICYVERS := 28
|
||||
|
||||
INSTALLED_KERNEL_TARGET := kernel
|
||||
|
|
|
@ -132,12 +132,18 @@ on boot
|
|||
chown system system /sys/devices/system/cpu/cpu0/cpufreq/boot_lock
|
||||
chmod 0660 /sys/devices/system/cpu/cpu0/cpufreq/boot_lock
|
||||
|
||||
chown system system /sys/devices/soc.0/cpu_budget_cool.17/roomage
|
||||
chmod 0660 /sys/devices/soc.0/cpu_budget_cool.17/roomage
|
||||
chown system system /sys/devices/soc.0/cpu_budget_cool.16/roomage
|
||||
chmod 0660 /sys/devices/soc.0/cpu_budget_cool.16/roomage
|
||||
|
||||
chown system system /sys/class/devfreq/dramfreq/adaptive/pause
|
||||
chmod 0660 /sys/class/devfreq/dramfreq/adaptive/pause
|
||||
|
||||
write /dev/cpuset/foreground/cpus 0-3
|
||||
write /dev/cpuset/foreground/boost/cpus 0-3
|
||||
write /dev/cpuset/background/cpus 0
|
||||
write /dev/cpuset/system-background/cpus 0-1
|
||||
write /dev/cpuset/top-app/cpus 0-3
|
||||
|
||||
on charger
|
||||
insmod nand.ko
|
||||
mount_all /fstab.sun50iw1p1
|
||||
|
@ -147,6 +153,21 @@ on charger
|
|||
write /sys/module/printk/parameters/console_suspend N
|
||||
write /proc/sys/kernel/printk 0
|
||||
|
||||
write /sys/devices/system/cpu/cpu0/cpufreq/boot_lock 1
|
||||
write /sys/devices/soc.0/cpu_budget_cool.16/roomage "0 4 0 0 1152000 4 0 0"
|
||||
write /sys/class/devfreq/dramfreq/adaptive/pause 0
|
||||
write /sys/devices/1c40000.gpu/dvfs/android 4
|
||||
write /sys/kernel/autohotplug/enable 1
|
||||
write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor powersave
|
||||
|
||||
on property:dev.bootcomplete=1
|
||||
write /sys/devices/system/cpu/cpu0/cpufreq/boot_lock 1 # AFTER_BOOT
|
||||
write /sys/devices/soc.0/cpu_budget_cool.16/roomage "0 4 0 0 1152000 4 0 0" # SCALE_UP_TO_4_CPUS
|
||||
write /sys/class/devfreq/dramfreq/adaptive/pause 1 # DISABLE_DRAM_CHANGE
|
||||
write /sys/devices/1c40000.gpu/dvfs/android 4 # GPU_NORMAL
|
||||
write /sys/kernel/autohotplug/enable 1 # AUTO DISCONNECT
|
||||
write /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor interactive # INTERACTIVE
|
||||
|
||||
ifeq ($(BOARD_WIDEVINE_OEMCRYPTO_LEVEL), 1)
|
||||
service optee /system/bin/tee_supplicant
|
||||
class core
|
||||
|
|
25
tulip-chiphd/power/Android.mk
Normal file
25
tulip-chiphd/power/Android.mk
Normal file
|
@ -0,0 +1,25 @@
|
|||
#
|
||||
# Copyright 2014 The Android Open Source 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_MODULE_RELATIVE_PATH := hw
|
||||
LOCAL_SRC_FILES := power_tulip.c
|
||||
LOCAL_SHARED_LIBRARIES := liblog libcutils
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE := power.tulip
|
||||
include $(BUILD_SHARED_LIBRARY)
|
297
tulip-chiphd/power/power_tulip.c
Normal file
297
tulip-chiphd/power/power_tulip.c
Normal file
|
@ -0,0 +1,297 @@
|
|||
/*
|
||||
* Copyright (C) 2014 The Android Open Source Project
|
||||
* Copyright (C) 2016 Kamil Trzciński
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
//
|
||||
// This is based on hammerhead power HAL from Android 5.1
|
||||
//
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
#include <fcntl.h>
|
||||
#include <dlfcn.h>
|
||||
#include <cutils/uevent.h>
|
||||
#include <errno.h>
|
||||
#include <sys/poll.h>
|
||||
#include <pthread.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#define LOG_TAG "PowerHAL"
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include <hardware/hardware.h>
|
||||
#include <hardware/power.h>
|
||||
|
||||
/* cpu spec files defined */
|
||||
#define ROOMAGE "/sys/devices/soc.0/cpu_budget_cool.16/roomage"
|
||||
#define CPUHOT "/sys/kernel/autohotplug/enable"
|
||||
#define CPU0GOV "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor"
|
||||
|
||||
/* gpu spec files defined */
|
||||
#define GPUFREQ "/sys/devices/1c40000.gpu/dvfs/android"
|
||||
|
||||
/* ddr spec files defined */
|
||||
#define DRAMFREQ "/sys/class/devfreq/dramfreq/cur_freq"
|
||||
#define DRAMPAUSE "/sys/class/devfreq/dramfreq/adaptive/pause"
|
||||
|
||||
/* value define */
|
||||
#define ROOMAGE_PERF "816000 4 0 0 1152000 4 0 0 0"
|
||||
#define ROOMAGE_NORMAL "0 0 0 0 1152000 4 0 0 0"
|
||||
#define ROOMAGE_VIDEO "0 0 0 0 1152000 4 0 0 0"
|
||||
|
||||
/* dram scene value defined */
|
||||
#define DRAM_NORMAL "0"
|
||||
#define DRAM_HOME "1"
|
||||
#define DRAM_LOCALVIDEO "2"
|
||||
#define DRAM_BGMUSIC "3"
|
||||
#define DRAM_4KLOCALVIDEO "4"
|
||||
|
||||
#define DRAM_PERF "1"
|
||||
#define DRAM_AUTO "0"
|
||||
|
||||
/* gpu scene value defined */
|
||||
#define GPU_NORMAL "4\n"
|
||||
#define GPU_HOME "4\n"
|
||||
#define GPU_LOCALVIDEO "4\n"
|
||||
#define GPU_BGMUSIC "4\n"
|
||||
#define GPU_4KLOCALVIDEO "4\n"
|
||||
#define GPU_PERF "8\n"
|
||||
|
||||
#define CPUGOV_INTERACTIVE "interactive"
|
||||
#define CPUGOV_POWERSAVE "powersave"
|
||||
|
||||
#define STATE_ON "state=1"
|
||||
#define STATE_OFF "state=0"
|
||||
#define STATE_HDR_ON "state=2"
|
||||
#define STATE_HDR_OFF "state=3"
|
||||
|
||||
#define MAX_LENGTH 50
|
||||
|
||||
#define UEVENT_MSG_LEN 2048
|
||||
#define TOTAL_CPUS 4
|
||||
#define UEVENT_STRING "online@/devices/system/cpu/"
|
||||
|
||||
static int last_state = -1;
|
||||
|
||||
static struct pollfd pfd;
|
||||
static bool low_power_mode = false;
|
||||
static pthread_mutex_t low_power_mode_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static const char *saved_write[16];
|
||||
|
||||
static int sysfs_write(int index, const char *path, const char *s)
|
||||
{
|
||||
if(saved_write[index] == s) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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 -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);
|
||||
return -1;
|
||||
}
|
||||
|
||||
close(fd);
|
||||
saved_write[index] = s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_state(const char *roomage, const char *cpu, const char *gpu)
|
||||
{
|
||||
sysfs_write(0, ROOMAGE, roomage);
|
||||
sysfs_write(1, CPU0GOV, cpu);
|
||||
sysfs_write(2, GPUFREQ, gpu);
|
||||
}
|
||||
|
||||
static int uevent_event()
|
||||
{
|
||||
char msg[UEVENT_MSG_LEN];
|
||||
char *cp;
|
||||
int n, cpu, ret;
|
||||
|
||||
n = recv(pfd.fd, msg, UEVENT_MSG_LEN, MSG_DONTWAIT);
|
||||
if (n <= 0) {
|
||||
return -1;
|
||||
}
|
||||
if (n >= UEVENT_MSG_LEN) { /* overflow -- discard */
|
||||
return -1;
|
||||
}
|
||||
|
||||
cp = msg;
|
||||
|
||||
if (strstr(cp, UEVENT_STRING)) {
|
||||
n = strlen(cp);
|
||||
errno = 0;
|
||||
cpu = strtol(cp + n - 1, NULL, 10);
|
||||
|
||||
if (errno == EINVAL || errno == ERANGE || cpu < 0 || cpu >= TOTAL_CPUS) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&low_power_mode_lock);
|
||||
// TODO: support this
|
||||
pthread_mutex_unlock(&low_power_mode_lock);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *thread_uevent(__attribute__((unused)) void *x)
|
||||
{
|
||||
while (1) {
|
||||
int nevents, ret;
|
||||
|
||||
nevents = poll(&pfd, 1, -1);
|
||||
|
||||
if (nevents == -1) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
ALOGE("powerhal: thread_uevent: poll_wait failed\n");
|
||||
break;
|
||||
}
|
||||
ret = uevent_event();
|
||||
if (ret < 0)
|
||||
ALOGE("Error processing the uevent event");
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void uevent_init()
|
||||
{
|
||||
struct sockaddr_nl client;
|
||||
pthread_t tid;
|
||||
pfd.fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
|
||||
|
||||
if (pfd.fd < 0) {
|
||||
ALOGE("%s: failed to open: %s", __func__, strerror(errno));
|
||||
return;
|
||||
}
|
||||
memset(&client, 0, sizeof(struct sockaddr_nl));
|
||||
pthread_create(&tid, NULL, thread_uevent, NULL);
|
||||
client.nl_family = AF_NETLINK;
|
||||
client.nl_pid = tid;
|
||||
client.nl_groups = -1;
|
||||
pfd.events = POLLIN;
|
||||
bind(pfd.fd, (void *)&client, sizeof(struct sockaddr_nl));
|
||||
return;
|
||||
}
|
||||
|
||||
static void power_init(__attribute__((unused)) struct power_module *module)
|
||||
{
|
||||
ALOGI("%s", __func__);
|
||||
uevent_init();
|
||||
}
|
||||
|
||||
static void process_video_encode_hint(void *metadata)
|
||||
{
|
||||
if (metadata) {
|
||||
if (!strncmp(metadata, STATE_ON, sizeof(STATE_ON))) {
|
||||
set_state(ROOMAGE_VIDEO, GPU_4KLOCALVIDEO, CPUGOV_INTERACTIVE);
|
||||
} else if (!strncmp(metadata, STATE_OFF, sizeof(STATE_OFF))) {
|
||||
set_state(ROOMAGE_NORMAL, GPU_NORMAL, CPUGOV_INTERACTIVE);
|
||||
} else if (!strncmp(metadata, STATE_HDR_ON, sizeof(STATE_HDR_ON))) {
|
||||
/* HDR usecase started */
|
||||
} else if (!strncmp(metadata, STATE_HDR_OFF, sizeof(STATE_HDR_OFF))) {
|
||||
/* HDR usecase stopped */
|
||||
}else
|
||||
return;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void power_set_interactive(__attribute__((unused)) struct power_module *module, int on)
|
||||
{
|
||||
if (last_state == -1) {
|
||||
last_state = on;
|
||||
} else {
|
||||
if (last_state == on)
|
||||
return;
|
||||
else
|
||||
last_state = on;
|
||||
}
|
||||
|
||||
ALOGV("%s %s", __func__, (on ? "ON" : "OFF"));
|
||||
if (on) {
|
||||
set_state(ROOMAGE_PERF, GPU_PERF, CPUGOV_INTERACTIVE);
|
||||
} else {
|
||||
set_state(ROOMAGE_NORMAL, GPU_NORMAL, CPUGOV_INTERACTIVE);
|
||||
}
|
||||
}
|
||||
|
||||
static void power_hint( __attribute__((unused)) struct power_module *module,
|
||||
power_hint_t hint, __attribute__((unused)) void *data)
|
||||
{
|
||||
int cpu, ret;
|
||||
|
||||
switch (hint) {
|
||||
case POWER_HINT_INTERACTION:
|
||||
ALOGV("POWER_HINT_INTERACTION");
|
||||
set_state(ROOMAGE_NORMAL, GPU_NORMAL, CPUGOV_INTERACTIVE);
|
||||
break;
|
||||
#if 0
|
||||
case POWER_HINT_VSYNC:
|
||||
ALOGV("POWER_HINT_VSYNC %s", (data ? "ON" : "OFF"));
|
||||
break;
|
||||
#endif
|
||||
case POWER_HINT_VIDEO_ENCODE:
|
||||
process_video_encode_hint(data);
|
||||
break;
|
||||
|
||||
case POWER_HINT_LOW_POWER:
|
||||
pthread_mutex_lock(&low_power_mode_lock);
|
||||
set_state(ROOMAGE_NORMAL, GPU_NORMAL, CPUGOV_POWERSAVE);
|
||||
pthread_mutex_unlock(&low_power_mode_lock);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct hw_module_methods_t power_module_methods = {
|
||||
.open = NULL,
|
||||
};
|
||||
|
||||
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 = "Tulip Power HAL",
|
||||
.author = "Kamil Trzciński <ayufan@ayufan.eu>",
|
||||
.methods = &power_module_methods,
|
||||
},
|
||||
|
||||
.init = power_init,
|
||||
.setInteractive = power_set_interactive,
|
||||
.powerHint = power_hint,
|
||||
};
|
|
@ -16,10 +16,12 @@ PRODUCT_PACKAGES += \
|
|||
ESFileExplorer \
|
||||
VideoPlayer \
|
||||
Bluetooth \
|
||||
ChromeBrowser
|
||||
ChromeBrowser \
|
||||
mtop
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
hdmi_cec.tulip
|
||||
hdmi_cec.tulip \
|
||||
power.tulip
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/softwinner/tulip-chiphd/kernel:kernel \
|
||||
|
|
|
@ -24,7 +24,8 @@ PRODUCT_PACKAGES += \
|
|||
SideloadLauncher
|
||||
|
||||
PRODUCT_PACKAGES += \
|
||||
hdmi_cec.tulip
|
||||
hdmi_cec.tulip \
|
||||
power.tulip
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
device/softwinner/tulip-chiphd/kernel:kernel \
|
||||
|
|
|
@ -141,9 +141,10 @@ tulip_sync() {
|
|||
set -xe
|
||||
adb wait-for-device
|
||||
adb remount
|
||||
# adb shell mount -o remount,rw /bootloader
|
||||
if ! adb shell mountpoint /bootloader; then
|
||||
adb shell mount -t vfat -o sync /dev/block/mmcblk0p1 /bootloader
|
||||
fi
|
||||
adb sync system
|
||||
#adb shell mount -t vfat -o sync /dev/block/mmcblk0p1 /bootloader
|
||||
for i in kernel ramdisk.img ramdisk-recovery.img; do
|
||||
adb push $ANDROID_PRODUCT_OUT/$i /bootloader/
|
||||
done
|
||||
|
|
Loading…
Reference in a new issue