summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);