From 5a3c2c33b700f293db222d928d17571d681d1aa8 Mon Sep 17 00:00:00 2001 From: Stefan Kalkowski Date: Mon, 24 Jun 2013 13:08:33 +0200 Subject: [PATCH] Add 'cpu_frequency' command to cli_monitor (fix #776) This commit extends the Fiasco.OC specific extensions of the cli_monitor to enable the user to interactively change or show current CPU frequency --- .../platform/arndale/regulator/consts.h | 24 +++++----- os/src/app/cli_monitor/foc/extension.cc | 37 +++++++++++++++ os/src/drivers/platform/arndale/cmu.h | 46 ++++++++++++++++--- 3 files changed, 88 insertions(+), 19 deletions(-) diff --git a/os/include/platform/arndale/regulator/consts.h b/os/include/platform/arndale/regulator/consts.h index 703256b06..7d4a64b49 100644 --- a/os/include/platform/arndale/regulator/consts.h +++ b/os/include/platform/arndale/regulator/consts.h @@ -60,18 +60,18 @@ namespace Regulator { ***************************************/ enum Cpu_clock_freq { - CPU_FREQ_200, - CPU_FREQ_400, - CPU_FREQ_600, - CPU_FREQ_800, - CPU_FREQ_1000, - CPU_FREQ_1200, - CPU_FREQ_1400, - CPU_FREQ_1600, - CPU_FREQ_1700, /* warning: 1700 not recommended by the reference manual - we just insert this for performance measurement against - Linux, which uses this overclocking */ - CPU_FREQ_MAX + CPU_FREQ_200 = 200000000, + CPU_FREQ_400 = 400000000, + CPU_FREQ_600 = 600000000, + CPU_FREQ_800 = 800000000, + CPU_FREQ_1000 = 1000000000, + CPU_FREQ_1200 = 1200000000, + CPU_FREQ_1400 = 1400000000, + CPU_FREQ_1600 = 1600000000, + CPU_FREQ_1700 = 1700000000, + /* warning: 1700 not recommended by the reference manual + we just insert this for performance measurement against + Linux, which uses this overclocking */ }; } diff --git a/os/src/app/cli_monitor/foc/extension.cc b/os/src/app/cli_monitor/foc/extension.cc index e0a35faf6..40b064e9a 100644 --- a/os/src/app/cli_monitor/foc/extension.cc +++ b/os/src/app/cli_monitor/foc/extension.cc @@ -11,9 +11,14 @@ * under the terms of the GNU General Public License version 2. */ +/* Genode includes */ +#include +#include + /* local includes */ #include #include +#include /* Fiasco includes */ namespace Fiasco { @@ -64,8 +69,40 @@ struct Reboot_command : Command }; +struct Cpufreq_command : Command +{ + Regulator::Connection ®ulator; + + Cpufreq_command(Regulator::Connection &r) + : Command("cpu_frequency", "set/show CPU frequency"), + regulator(r) { } + + void execute(Command_line &cmd, Terminal::Session &terminal) + { + char freq[128]; + freq[0] = 0; + if (cmd.argument(0, freq, sizeof(freq)) == false) { + tprintf(terminal, "Current CPU frequency: %ld Hz\n", + regulator.level()); + return; + } + + unsigned long f = 0; + Genode::ascii_to(freq, &f, 10); + tprintf(terminal, "set frequency to %ld Hz\n", f); + regulator.set_level(f); + } +}; + + void init_extension(Command_registry &commands) { + try { /* only inserts commands if route to regulator session exists */ + static Regulator::Connection reg(Regulator::CLK_CPU); + static Cpufreq_command cpufreq_command(reg); + commands.insert(&cpufreq_command); + } catch (...) { PDBG("No regulator session available!"); }; + static Kdebug_command kdebug_command; commands.insert(&kdebug_command); diff --git a/os/src/drivers/platform/arndale/cmu.h b/os/src/drivers/platform/arndale/cmu.h index 0f1276590..121217de5 100644 --- a/os/src/drivers/platform/arndale/cmu.h +++ b/os/src/drivers/platform/arndale/cmu.h @@ -236,8 +236,44 @@ class Cmu : public Regulator::Driver, Cpu_clock_freq _cpu_freq; - void _cpu_clk_freq(Cpu_clock_freq freq) + void _cpu_clk_freq(unsigned long level) { + unsigned freq; + switch (level) { + case CPU_FREQ_200: + freq = 0; + break; + case CPU_FREQ_400: + freq = 1; + break; + case CPU_FREQ_600: + freq = 2; + break; + case CPU_FREQ_800: + freq = 3; + break; + case CPU_FREQ_1000: + freq = 4; + break; + case CPU_FREQ_1200: + freq = 5; + break; + case CPU_FREQ_1400: + freq = 6; + break; + case CPU_FREQ_1600: + freq = 7; + break; + case CPU_FREQ_1700: + freq = 8; + break; + default: + PWRN("Unsupported CPU frequency level %ld", level); + PWRN("Supported values are 200, 400, 600, 800 MHz"); + PWRN("and 1, 1.2, 1.4, 1.6, 1.7 GHz"); + return; + }; + /** * change clock divider values */ @@ -276,7 +312,7 @@ class Cmu : public Regulator::Driver, while (read() != Clk_mux_stat_cpu::Cpu_sel::MOUT_APLL) ; - _cpu_freq = freq; + _cpu_freq = static_cast(level); } @@ -408,11 +444,7 @@ class Cmu : public Regulator::Driver, { switch (id) { case CLK_CPU: - if (level >= CPU_FREQ_MAX) { - PWRN("level=%ld not supported", level); - return; - } - _cpu_clk_freq(static_cast(level)); + _cpu_clk_freq(level); break; default: PWRN("Unsupported for %s", names[id].name);