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.tar.gz
rockbox-6d3dc8fce0401da24ad45593e4eb9a68e2cde297.zip
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 75e23b3945..e602b713c3 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,
244 { 244 {
245 int cpu = (selected_item - 5) / (state_count + 1); 245 int cpu = (selected_item - 5) / (state_count + 1);
246 int cpu_line = (selected_item - 5) % (state_count + 1); 246 int cpu_line = (selected_item - 5) % (state_count + 1);
247#if defined(DX50) || defined(DX90)
248 int min_freq = min_scaling_frequency(cpu);
249 int cur_freq = current_scaling_frequency(cpu);
250 int max_freq = max_scaling_frequency(cpu);
251 char governor[20];
252 bool have_governor = current_scaling_governor(cpu, governor, sizeof(governor));
253 if(cpu_line == 0)
254 {
255 sprintf(buffer,
256 " CPU%d: %s: %d/%d/%d MHz",
257 cpu,
258 have_governor ? governor : "Min/Cur/Max freq",
259 min_freq > 0 ? min_freq/1000 : -1,
260 cur_freq > 0 ? cur_freq/1000 : -1,
261 max_freq > 0 ? max_freq/1000 : -1);
262 }
263#else
247 int freq1 = frequency_linux(cpu, false); 264 int freq1 = frequency_linux(cpu, false);
248 int freq2 = frequency_linux(cpu, true); 265 int freq2 = frequency_linux(cpu, true);
249 if (cpu_line == 0) 266 if (cpu_line == 0)
@@ -252,6 +269,7 @@ static const char* get_cpuinfo(int selected_item, void *data,
252 freq1 > 0 ? freq1/1000 : -1, 269 freq1 > 0 ? freq1/1000 : -1,
253 freq2 > 0 ? freq2/1000 : -1); 270 freq2 > 0 ? freq2/1000 : -1);
254 } 271 }
272#endif
255 else 273 else
256 { 274 {
257 cpustatetimes_linux(cpu, states, ARRAYLEN(states)); 275 cpustatetimes_linux(cpu, states, ARRAYLEN(states));
diff --git a/firmware/target/hosted/cpuinfo-linux.c b/firmware/target/hosted/cpuinfo-linux.c
index e0a6bd76da..8158673349 100644
--- a/firmware/target/hosted/cpuinfo-linux.c
+++ b/firmware/target/hosted/cpuinfo-linux.c
@@ -35,8 +35,14 @@
35#include "cpuinfo-linux.h" 35#include "cpuinfo-linux.h"
36#include "gcc_extensions.h" 36#include "gcc_extensions.h"
37 37
38#if defined(DX50) || defined(DX90)
39#include <limits.h>
40#include <string.h>
41#include "debug.h"
42#endif
43
38#undef open /* want the *real* open here, not sim_open or the like */ 44#undef open /* want the *real* open here, not sim_open or the like */
39#if (CONFIG_PLATFORM & PLATFORM_ANDROID) 45#if (CONFIG_PLATFORM & PLATFORM_ANDROID) || defined(DX50) || defined(DX90)
40#include "cpu-features.h" 46#include "cpu-features.h"
41#define get_nprocs android_getCpuCount 47#define get_nprocs android_getCpuCount
42#endif 48#endif
@@ -154,6 +160,132 @@ int frequency_linux(int cpu, bool scaling)
154 return ret; 160 return ret;
155} 161}
156 162
163#if defined(DX50) || defined(DX90)
164bool current_scaling_governor(int cpu, char* governor, int governor_size)
165{
166 if((cpu < 0) || (governor == NULL) || (governor_size <= 0))
167 {
168 return false;
169 }
170
171 char path[PATH_MAX];
172 snprintf(path,
173 sizeof(path),
174 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor",
175 cpu);
176 FILE *f = fopen(path, "r");
177 if(f == NULL)
178 {
179 DEBUGF("ERROR %s: Can not open %s for reading.", __func__, path);
180 return false;
181 }
182
183 if(fgets(governor, governor_size, f) == NULL)
184 {
185 DEBUGF("ERROR %s: Read failed for %s.", __func__, path);
186 fclose(f);
187 return false;
188 }
189
190 if(strlen(governor) > 0)
191 {
192 governor[strlen(governor) - 1] = '\0';
193 }
194
195 fclose(f);
196 return true;
197}
198
199
200enum cpu_frequency_options
201{
202 SCALING_MIN_FREQ = 0,
203 SCALING_CUR_FREQ,
204 SCALING_MAX_FREQ
205};
206
207
208static int read_cpu_frequency(int cpu, enum cpu_frequency_options freqOpt)
209{
210 if(cpu < 0)
211 {
212 return -1;
213 }
214
215 char path[PATH_MAX];
216 switch(freqOpt)
217 {
218 case SCALING_MIN_FREQ:
219 {
220 snprintf(path,
221 PATH_MAX,
222 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_min_freq",
223 cpu);
224 break;
225 }
226
227 case SCALING_CUR_FREQ:
228 {
229 snprintf(path,
230 PATH_MAX,
231 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq",
232 cpu);
233 break;
234 }
235
236 case SCALING_MAX_FREQ:
237 {
238 snprintf(path,
239 PATH_MAX,
240 "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq",
241 cpu);
242 break;
243 }
244
245 default:
246 {
247 DEBUGF("ERROR %s: Unknown CpuFrequencyOptions: %d.", __func__, freqOpt);
248 return -1;
249 }
250 }
251
252 FILE *f = fopen(path, "r");
253 if(f == NULL)
254 {
255 DEBUGF("ERROR %s: Can not open %s for reading.", __func__, path);
256 return -1;
257 }
258
259 int freq;
260 if(fscanf(f, "%d", &freq) == EOF)
261 {
262 DEBUGF("ERROR %s: Read failed for %s.", __func__, path);
263 freq = -1;
264 }
265
266 fclose(f);
267 return(freq);
268}
269
270
271int min_scaling_frequency(int cpu)
272{
273 return(read_cpu_frequency(cpu, SCALING_MIN_FREQ));
274}
275
276
277int current_scaling_frequency(int cpu)
278{
279 return(read_cpu_frequency(cpu, SCALING_CUR_FREQ));
280}
281
282
283int max_scaling_frequency(int cpu)
284{
285 return(read_cpu_frequency(cpu, SCALING_MAX_FREQ));
286}
287#endif
288
157int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements) 289int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements)
158{ 290{
159 int elements_left = max_elements, cpu_dev; 291 int elements_left = max_elements, cpu_dev;
diff --git a/firmware/target/hosted/cpuinfo-linux.h b/firmware/target/hosted/cpuinfo-linux.h
index ebc05d5c43..0483a3a9aa 100644
--- a/firmware/target/hosted/cpuinfo-linux.h
+++ b/firmware/target/hosted/cpuinfo-linux.h
@@ -40,6 +40,28 @@ struct time_state {
40 40
41int cpuusage_linux(struct cpuusage* u); 41int cpuusage_linux(struct cpuusage* u);
42int frequency_linux(int cpu, bool scaling); 42int frequency_linux(int cpu, bool scaling);
43
44#if defined(DX50) || defined(DX90)
45/*
46 Get the current cpufreq scaling governor.
47 cpu [in]: The number of the cpu to query.
48 governor [out]: Buffer for the governor.
49 governor_size [in]: Size of the buffer for the governor.
50 Returns true on success, false else.
51*/
52bool current_scaling_governor(int cpu, char* governor, int governor_size);
53
54
55/*
56 Get the minimum, current or maximum cpufreq scaling frequency.
57 cpu [in]: The number of the cpu to query.
58 Returns -1 failure.
59*/
60int min_scaling_frequency(int cpu);
61int current_scaling_frequency(int cpu);
62int max_scaling_frequency(int cpu);
63#endif
64
43int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements); 65int cpustatetimes_linux(int cpu, struct time_state* data, int max_elements);
44int cpucount_linux(void); 66int cpucount_linux(void);
45 67