diff mbox

[RFC,1/1] ARM: print MHz in /proc/cpuinfo

Message ID 1465333713-14339-2-git-send-email-jon.mason@broadcom.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jon Mason June 7, 2016, 9:08 p.m. UTC
Query the CPU core clock in the device tree to determine the core clock
speed.  Output this clock rate in /proc/cpuinfo to match the output
from other architectures.  The output is intentionally patterned after
the x86 output, to match existing (and possibly expected) convention.

If any errors are encountered in querying the clock (or the speed is
erroneously zero), nothing will be printed out.  Thus any existing
devices that do not have CPU clocks defined in the device tree will
work as before.

Signed-off-by: Jon Mason <jon.mason@broadcom.com>
---
 arch/arm/kernel/setup.c | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

Comments

Sudeep Holla June 8, 2016, 8:34 a.m. UTC | #1
On 07/06/16 22:08, Jon Mason wrote:
> Query the CPU core clock in the device tree to determine the core clock
> speed.

How do guarantee that it's the current frequency of the CPU ?
It doesn't even represent the mix or max frequency, so it's incorrect.
Some DTs have boot frequency in that entry.

> Output this clock rate in /proc/cpuinfo to match the output
> from other architectures.  The output is intentionally patterned after
> the x86 output, to match existing (and possibly expected) convention.
>
> If any errors are encountered in querying the clock (or the speed is
> erroneously zero), nothing will be printed out.  Thus any existing
> devices that do not have CPU clocks defined in the device tree will
> work as before.
>

What if they just don't have in DT but have DVFS support ?

Also whey do we need this support when the user-space can query the
CPUFreq sysfs which is more accurate and maintains the current running
frequency ?
Jon Mason June 8, 2016, 7:31 p.m. UTC | #2
On Wed, Jun 08, 2016 at 09:34:06AM +0100, Sudeep Holla wrote:
> 
> 
> On 07/06/16 22:08, Jon Mason wrote:
> >Query the CPU core clock in the device tree to determine the core clock
> >speed.
> 
> How do guarantee that it's the current frequency of the CPU ?

I am basing it on the assumption (perhaps incorrect) that the clock in
the CPU DT corresponds to the one determining the CPU clock rate.  And,
that this clock rate is accurate in describing the speed at which the
CPU is currently running.

> It doesn't even represent the mix or max frequency, so it's incorrect.
> Some DTs have boot frequency in that entry.
> 
> >Output this clock rate in /proc/cpuinfo to match the output
> >from other architectures.  The output is intentionally patterned after
> >the x86 output, to match existing (and possibly expected) convention.
> >
> >If any errors are encountered in querying the clock (or the speed is
> >erroneously zero), nothing will be printed out.  Thus any existing
> >devices that do not have CPU clocks defined in the device tree will
> >work as before.
> >
> 
> What if they just don't have in DT but have DVFS support ?

This can be extended to cover DVFS or SMC calls or anything else.
This was simply a first step to cover what appeared to be the most
prevalent case.

> Also whey do we need this support when the user-space can query the
> CPUFreq sysfs which is more accurate and maintains the current running
> frequency ?

This is exactly what x86 is doing to provide its value in
/proc/cpuinfo.  I could easily augment this patch to call
cpufreq_quick_get(), if it returns 0, then call clk_get_rate().  If
both return 0, then simply not print out anything (which would cover
all of the possibilities).  Or, I could have it just call
cpufreq_quick_get() to get the value.

Thanks,
Jon

> 
> -- 
> Regards,
> Sudeep
Sudeep Holla June 9, 2016, 9:09 a.m. UTC | #3
On 08/06/16 20:31, Jon Mason wrote:
> On Wed, Jun 08, 2016 at 09:34:06AM +0100, Sudeep Holla wrote:
>>
>>
>> On 07/06/16 22:08, Jon Mason wrote:
>>> Query the CPU core clock in the device tree to determine the core clock
>>> speed.
>>
>> How do guarantee that it's the current frequency of the CPU ?
>
> I am basing it on the assumption (perhaps incorrect) that the clock in
> the CPU DT corresponds to the one determining the CPU clock rate.  And,
> that this clock rate is accurate in describing the speed at which the
> CPU is currently running.
>

As you already noticed, it's not always correct.

[..]

>>
>> What if they just don't have in DT but have DVFS support ?
>
> This can be extended to cover DVFS or SMC calls or anything else.
> This was simply a first step to cover what appeared to be the most
> prevalent case.
>

Using DVFS/CPUFreq makes this DT based approach irrelevant.

>> Also whey do we need this support when the user-space can query the
>> CPUFreq sysfs which is more accurate and maintains the current running
>> frequency ?
>
> This is exactly what x86 is doing to provide its value in
> /proc/cpuinfo.  I could easily augment this patch to call
> cpufreq_quick_get(), if it returns 0, then call clk_get_rate().  If
> both return 0, then simply not print out anything (which would cover
> all of the possibilities).  Or, I could have it just call
> cpufreq_quick_get() to get the value.
>

Agree x86 has, may be for legacy reasons. It even has CPUFreq sysfs
entries which is architecture agnostic while /proc/cpuinfo is more
architecture based. So applications that want to be portable across
architectures must choose the generic CPUFreq sysfs path rather than
some x86 based cpuinfo.
Jon Mason June 9, 2016, 5:36 p.m. UTC | #4
On Thu, Jun 9, 2016 at 5:09 AM, Sudeep Holla <sudeep.holla@arm.com> wrote:
>
>
> On 08/06/16 20:31, Jon Mason wrote:
>>
>> On Wed, Jun 08, 2016 at 09:34:06AM +0100, Sudeep Holla wrote:
>>>
>>>
>>>
>>> On 07/06/16 22:08, Jon Mason wrote:
>>>>
>>>> Query the CPU core clock in the device tree to determine the core clock
>>>> speed.
>>>
>>>
>>> How do guarantee that it's the current frequency of the CPU ?
>>
>>
>> I am basing it on the assumption (perhaps incorrect) that the clock in
>> the CPU DT corresponds to the one determining the CPU clock rate.  And,
>> that this clock rate is accurate in describing the speed at which the
>> CPU is currently running.
>>
>
> As you already noticed, it's not always correct.
>
> [..]
>
>>>
>>> What if they just don't have in DT but have DVFS support ?
>>
>>
>> This can be extended to cover DVFS or SMC calls or anything else.
>> This was simply a first step to cover what appeared to be the most
>> prevalent case.
>>
>
> Using DVFS/CPUFreq makes this DT based approach irrelevant.
>
>>> Also whey do we need this support when the user-space can query the
>>> CPUFreq sysfs which is more accurate and maintains the current running
>>> frequency ?
>>
>>
>> This is exactly what x86 is doing to provide its value in
>> /proc/cpuinfo.  I could easily augment this patch to call
>> cpufreq_quick_get(), if it returns 0, then call clk_get_rate().  If
>> both return 0, then simply not print out anything (which would cover
>> all of the possibilities).  Or, I could have it just call
>> cpufreq_quick_get() to get the value.
>>
>
> Agree x86 has, may be for legacy reasons. It even has CPUFreq sysfs
> entries which is architecture agnostic while /proc/cpuinfo is more
> architecture based. So applications that want to be portable across
> architectures must choose the generic CPUFreq sysfs path rather than
> some x86 based cpuinfo.

Thank you for educating me.  I am taking this (and RMK's comment) as
any modification to add CPU speed to /proc/cpuinfo is not welcomed,
anyone who wants to query this should instead look at cpufreq in
sysfs, and any dev who wants to add such a thing should look into
writing a driver in drivers/cpufreq/.

Thanks,
Jon

>
> --
> Regards,
> Sudeep
diff mbox

Patch

diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 7b53500..0c3e25a 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -33,6 +33,7 @@ 
 #include <linux/compiler.h>
 #include <linux/sort.h>
 #include <linux/psci.h>
+#include <linux/clk.h>
 
 #include <asm/unified.h>
 #include <asm/cp15.h>
@@ -1178,10 +1179,32 @@  static const char *hwcap2_str[] = {
 	NULL
 };
 
+static unsigned long cpu_freq(unsigned int core)
+{
+	struct device_node *np;
+	struct clk *c;
+	unsigned long rate = 0;
+
+	np = of_get_cpu_node(core, NULL);
+	if (!np)
+		goto err;
+
+	c = of_clk_get_by_name(np, NULL);
+	if (IS_ERR(c))
+		goto err;
+
+	rate = clk_get_rate(c);
+
+	clk_put(c);
+err:
+	return rate;
+}
+
 static int c_show(struct seq_file *m, void *v)
 {
 	int i, j;
 	u32 cpuid;
+	unsigned long rate;
 
 	for_each_online_cpu(i) {
 		/*
@@ -1194,6 +1217,12 @@  static int c_show(struct seq_file *m, void *v)
 		seq_printf(m, "model name\t: %s rev %d (%s)\n",
 			   cpu_name, cpuid & 15, elf_platform);
 
+		rate = cpu_freq(i);
+		if (rate)
+			/* Change from Hz into MHz */
+			seq_printf(m, "cpu MHz\t\t: %lu.%03lu\n",
+				   rate / 1000000, rate / 1000 % 1000);
+
 #if defined(CONFIG_SMP)
 		seq_printf(m, "BogoMIPS\t: %lu.%02lu\n",
 			   per_cpu(cpu_data, i).loops_per_jiffy / (500000UL/HZ),