powerHAL: Add interface for GPU and DDR performance boosting
For UI performance we need to ensure GPU and DDR frequency to meet the
performance requirement, otherwise even set the CPU boost margin to high
value but the bottleneck is GPU or DDR side but not CPU. So this commit
introduces the interface to support GPU and DDR performance boosting.
After profiling on Hikey960, this patch adds the related performance
boosting parameters for it. The DDR is set to 685MHz as minimum
frequency and GPU is set to 960MHz as minimum value.
Change-Id: Id5f6b0605a90f76cf55d891f4b7df3c0bf193aee
Signed-off-by: Leo Yan <leo.yan@linaro.org>
diff --git a/init.hikey960.power.rc b/init.hikey960.power.rc
index 13fb587..55a325f 100644
--- a/init.hikey960.power.rc
+++ b/init.hikey960.power.rc
@@ -16,6 +16,8 @@
chown system system /dev/stune/foreground/schedtune.boost
chown system system /dev/stune/foreground/schedtune.prefer_idle
chown system system /dev/stune/schedtune.boost
+ chown system system /sys/class/devfreq/ddr_devfreq/min_freq
+ chown system system /sys/class/devfreq/e82c0000.mali/min_freq
write /dev/stune/top-app/schedtune.boost 50
write /dev/stune/top-app/schedtune.prefer_idle 1
@@ -30,3 +32,9 @@
setprop ro.config.cpufreq.low_power_max.cluster0 "999000"
setprop ro.config.cpufreq.max_freq.cluster1 "/sys/devices/system/cpu/cpu4/cpufreq/scaling_max_freq"
setprop ro.config.cpufreq.low_power_max.cluster1 "903000"
+
+ setprop ro.config.devfreq.ddr.min_freq.path "/sys/class/devfreq/ddr_devfreq/min_freq"
+ setprop ro.config.devfreq.ddr.min_freq.boost "685000000"
+
+ setprop ro.config.devfreq.gpu.min_freq.path "/sys/class/devfreq/e82c0000.mali/min_freq"
+ setprop ro.config.devfreq.gpu.min_freq.boost "960000000"
diff --git a/power/power_hikey.c b/power/power_hikey.c
index 4661702..2bcd296 100644
--- a/power/power_hikey.c
+++ b/power/power_hikey.c
@@ -46,6 +46,24 @@
char schedtune_boost_interactive[PROPERTY_VALUE_MAX] = SCHEDTUNE_BOOST_VAL_DEFAULT;
long long schedtune_boost_time_ns = 1000000000LL;
+#define DEVFREQ_DDR_MIN_FREQ_PATH_PROP \
+ "ro.config.devfreq.ddr.min_freq.path"
+#define DEVFREQ_DDR_MIN_FREQ_BOOST_PROP \
+ "ro.config.devfreq.ddr.min_freq.boost"
+
+char devfreq_ddr_min_path[PROPERTY_VALUE_MAX];
+char devfreq_ddr_min_orig[PROPERTY_VALUE_MAX];
+char devfreq_ddr_min_boost[PROPERTY_VALUE_MAX];
+
+#define DEVFREQ_GPU_MIN_FREQ_PATH_PROP \
+ "ro.config.devfreq.gpu.min_freq.path"
+#define DEVFREQ_GPU_MIN_FREQ_BOOST_PROP \
+ "ro.config.devfreq.gpu.min_freq.boost"
+
+char devfreq_gpu_min_path[PROPERTY_VALUE_MAX];
+char devfreq_gpu_min_orig[PROPERTY_VALUE_MAX];
+char devfreq_gpu_min_boost[PROPERTY_VALUE_MAX];
+
#define INTERACTIVE_BOOSTPULSE_PATH "/sys/devices/system/cpu/cpufreq/interactive/boostpulse"
#define INTERACTIVE_IO_IS_BUSY_PATH "/sys/devices/system/cpu/cpufreq/interactive/io_is_busy"
@@ -77,7 +95,6 @@
char low_power_max[PROPERTY_VALUE_MAX];
} hikey_cpufreq_clusters[NR_CLUSTERS];
-
#define container_of(addr, struct_name, field_name) \
((struct_name *)((char *)(addr) - offsetof(struct_name, field_name)))
@@ -192,6 +209,43 @@
return 0;
}
+static void
+hikey_devfreq_set_interactive(struct hikey_power_module __unused *hikey, int on)
+{
+ if (!on || low_power_mode) {
+ if (devfreq_ddr_min_path[0] != '\0')
+ sysfs_write(devfreq_ddr_min_path, devfreq_ddr_min_orig);
+
+ if (devfreq_gpu_min_path[0] != '\0')
+ sysfs_write(devfreq_gpu_min_path, devfreq_gpu_min_orig);
+ } else {
+ if (devfreq_ddr_min_path[0] != '\0')
+ sysfs_write(devfreq_ddr_min_path, devfreq_ddr_min_boost);
+
+ if (devfreq_gpu_min_path[0] != '\0')
+ sysfs_write(devfreq_gpu_min_path, devfreq_gpu_min_boost);
+ }
+}
+
+static void hikey_devfreq_init(struct hikey_power_module __unused *hikey)
+{
+ property_get(DEVFREQ_DDR_MIN_FREQ_PATH_PROP, devfreq_ddr_min_path, "");
+ if (devfreq_ddr_min_path[0] != '\0') {
+ sysfs_read(devfreq_ddr_min_path, devfreq_ddr_min_orig,
+ PROPERTY_VALUE_MAX);
+ property_get(DEVFREQ_DDR_MIN_FREQ_BOOST_PROP,
+ devfreq_ddr_min_boost, "");
+ }
+
+ property_get(DEVFREQ_GPU_MIN_FREQ_PATH_PROP, devfreq_gpu_min_path, "");
+ if (devfreq_gpu_min_path[0] != '\0') {
+ sysfs_read(devfreq_gpu_min_path, devfreq_gpu_min_orig,
+ PROPERTY_VALUE_MAX);
+ property_get(DEVFREQ_GPU_MIN_FREQ_BOOST_PROP,
+ devfreq_gpu_min_boost, "");
+ }
+}
+
/*[schedtune functions]*******************************************************/
int schedtune_sysfs_boost(struct hikey_power_module *hikey, char* booststr)
@@ -229,6 +283,7 @@
}
schedtune_sysfs_boost(hikey, schedtune_boost_norm);
+ hikey_devfreq_set_interactive(hikey, 0);
hikey->deboost_time = 0;
pthread_mutex_unlock(&hikey->lock);
break;
@@ -247,6 +302,7 @@
now = gettime_ns();
if (!hikey->deboost_time) {
schedtune_sysfs_boost(hikey, schedtune_boost_interactive);
+ hikey_devfreq_set_interactive(hikey, 1);
sem_post(&hikey->signal_lock);
}
hikey->deboost_time = now + schedtune_boost_time_ns;
@@ -340,12 +396,12 @@
max_clusters = i;
}
-
static void hikey_power_init(struct power_module __unused *module)
{
struct hikey_power_module *hikey = container_of(module,
struct hikey_power_module, base);
hikey_cpufreq_init(hikey);
+ hikey_devfreq_init(hikey);
interactive_power_init(hikey);
schedtune_power_init(hikey);
}