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 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