summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUdo Schläpfer <rockbox-2014.10@desktopwarrior.net>2014-12-13 20:45:03 +0100
committerGerrit Rockbox <gerrit@rockbox.org>2015-01-30 20:15:21 +0100
commit6d3dc8fce0401da24ad45593e4eb9a68e2cde297 (patch)
tree48e61a3d6a99141dc2b1e6cf6037adbd0e58f056
parent572b36a51a7796e88c11cf0658ced40c1a6efece (diff)
downloadrockbox-6d3dc8fce0401da24ad45593e4eb9a68e2cde297.zip
rockbox-6d3dc8fce0401da24ad45593e4eb9a68e2cde297.tar.gz
rockbox-6d3dc8fce0401da24ad45593e4eb9a68e2cde297.tar.bz2
rockbox-6d3dc8fce0401da24ad45593e4eb9a68e2cde297.tar.xz
iBasso DX50/DX90: CPU info enhancements.
System -> Debug (Keep Out) -> View CPU stats Will now show the current cpufreq scaling governor, minimum, current and maximum cpufreq scaling frequency for each CPU. This may be genric for Android kernel based devices but is only enabled for iBasso Devices. Other maintainers may choose do adopt this. Change-Id: I53e212f8707bf2abaa557e297293fb559ac37058
-rw-r--r--apps/debug_menu.c18
-rw-r--r--firmware/target/hosted/cpuinfo-linux.c134
-rw-r--r--firmware/target/hosted/cpuinfo-linux.h22
3 files changed, 173 insertions, 1 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 75e23b3..e602b71 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -244,6 +244,23 @@ static const char* get_cpuinfo(int selected_item, void *data,
{
int cpu = (selected_item - 5) / (state_count + 1);
int cpu_line = (selected_item - 5) % (state_count + 1);
+#if defined(DX50) || defined(DX90)
+ int min_freq = min_scaling_frequency(cpu);
+ int cur_freq = current_scaling_frequency(cpu);
+ int max_freq = max_scaling_frequency(cpu);
+ char governor[20];
+ bool have_governor = current_scaling_governor(cpu, governor, sizeof(governor));
+ if(cpu_line == 0)
+ {
+ sprintf(buffer,
+ " CPU%d: %s: %d/%d/%d MHz",
+ cpu,
+ have_governor ? governor : "Min/Cur/Max freq",
+ min_freq > 0 ? min_freq/1000 : -1,
+ cur_freq > 0 ? cur_freq/1000 : -1,
+ max_freq > 0 ? max_freq/1000 : -1);
+ }
+#else
int freq1 = frequency_linux(cpu, false);
int freq2 = frequency_linux(cpu, true);
if (cpu_line == 0)
@@ -252,6 +269,7 @@ static const char* get_cpuinfo(int selected_item, void *data,
freq1 > 0 ? freq1/1000 : -1,
freq2 > 0 ? freq2/1000 : -1);
}
+#endif
else
{
cpustatetimes_linux(cpu, states, ARRAYLEN(states));
diff --git a/firmware/target/hosted/cpuinfo-linux.c b/firmware/target/hosted/cpuinfo-linux.c
index e0a6bd7..8158673 100644
--- a/firmware/target/hosted/cpuinfo-linux.c
+++ b/firmware/target/hosted/cpuinfo-linux.c
@@ -35,8 +35,14 @@
#include "cpuinfo-linux.h"
#include "gcc_extensions.h"
+#if defined(DX50) || defined(DX90)
+#include <limits.h>
+#include <string.h>
+#include "debug.h"
+#endif
+
#undef open /* want the *real* open here, not sim_open or the like */
-#if (CONFIG_PLATFORM & PLATFORM_ANDROID)
+#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(DX50) || defined(DX90)
#include "cpu-features.h"
#define get_nprocs android_getCpuCount
#endif
@@ -154,6 +160,132 @@ int frequency_linux(int cpu, bool scaling)
return ret;
}
+#if defined(DX50) || defined(DX90)
+bool current_scaling_governor(int cpu, char* governor, int governor_size)
+{
+ if((cpu < 0) || (governor == NULL) || (governor_size <= 0))
+ {
+ return false;
+ }
+
+ char path[PATH_MAX];
+ snprintf(path,
+ sizeof(path),
+ "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
+ cpu);
+ FILE *f = fopen(path, "r");
+ if(f == NULL)
+ {
+ DEBUGF("ERROR %s: Can not open %s for reading.", __func__, path);
+ return false;
+ }
+
+ if(fgets(governor, governor_size, f) == NULL)
+ {
+ DEBUGF("ERROR %s: Read failed for %s.", __func__, path);
+ fclose(f);
+ return false;
+ }
+
+ if(strlen(governor) > 0)
+ {
+ governor[strlen(governor) - 1] = '\0';
+ }
+
+ fclose(f);
+ return true;
+}
+
+
+enum cpu_frequency_options
+{
+ SCALING_MIN_FREQ = 0,
+ SCALING_CUR_FREQ,
+ SCALING_MAX_FREQ
+};
+
+
+static int read_cpu_frequency(int cpu, enum cpu_frequency_options freqOpt)
+{
+ if(cpu < 0)
+ {
+ return -1;
+ }
+
+ char path[PATH_MAX];
+ switch(freqOpt)
+ {
+ case SCALING_MIN_FREQ:
+ {
+ snprintf(path,
+ PATH_MAX,
+ "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq",
+ cpu);
+ break;
+ }
+
+ case SCALING_CUR_FREQ:
+ {
+ snprintf(path,
+ PATH_MAX,
+ "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq",
+ cpu);
+ break;
+ }
+
+ case SCALING_MAX_FREQ:
+ {
+ snprintf(path,
+ PATH_MAX,
+ "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq",
+ cpu);
+ break;
+ }
+
+ default:
+ {
+ DEBUGF("ERROR %s: Unknown CpuFrequencyOptions: %d.", __func__, freqOpt);
+ return -1;
+ }
+ }
+
+ FILE *f = fopen(path, "r");
+ if(f == NULL)
+ {
+ DEBUGF("ERROR %s: Can not open %s for reading.", __func__, path);
+ return -1;
+ }
+
+ int freq;
+ if(fscanf(f, "%d", &freq) == EOF)
+ {
+ DEBUGF("ERROR %s: Read failed for %s.", __func__, path);
+ freq = -1;
+ }
+
+ fclose(f);
+ return(freq);
+}
+
+
+int min_scaling_frequency(int cpu)
+{
+ return(read_cpu_frequency(cpu, SCALING_MIN_FREQ));
+}
+
+
+int current_scaling_frequency(int cpu)
+{
+ return(read_cpu_frequency(cpu, SCALING_CUR_FREQ));
+}
+
+
+int max_scaling_frequency(int cpu)
+{
+ return(read_cpu_frequency(cpu, SCALING_MAX_FREQ));
+}
+#endif
+
int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements)
{
int elements_left = max_elements, cpu_dev;
diff --git a/firmware/target/hosted/cpuinfo-linux.h b/firmware/target/hosted/cpuinfo-linux.h
index ebc05d5..0483a3a 100644
--- a/firmware/target/hosted/cpuinfo-linux.h
+++ b/firmware/target/hosted/cpuinfo-linux.h
@@ -40,6 +40,28 @@ struct time_state {
int cpuusage_linux(struct cpuusage* u);
int frequency_linux(int cpu, bool scaling);
+
+#if defined(DX50) || defined(DX90)
+/*
+ Get the current cpufreq scaling governor.
+ cpu [in]: The number of the cpu to query.
+ governor [out]: Buffer for the governor.
+ governor_size [in]: Size of the buffer for the governor.
+ Returns true on success, false else.
+*/
+bool current_scaling_governor(int cpu, char* governor, int governor_size);
+
+
+/*
+ Get the minimum, current or maximum cpufreq scaling frequency.
+ cpu [in]: The number of the cpu to query.
+ Returns -1 failure.
+*/
+int min_scaling_frequency(int cpu);
+int current_scaling_frequency(int cpu);
+int max_scaling_frequency(int cpu);
+#endif
+
int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements);
int cpucount_linux(void);