From: Mason <mpeg.blue@free.fr>
To: Linux ARM <linux-arm-kernel@lists.infradead.org>,
Linux PM <linux-pm@vger.kernel.org>,
cpufreq <cpufreq@vger.kernel.org>
Cc: "Rafael J. Wysocki" <rjw@rjwysocki.net>,
Viresh Kumar <viresh.kumar@linaro.org>
Subject: Re: RFC on cpufreq implementation
Date: Thu, 29 Jan 2015 17:43:19 +0100 [thread overview]
Message-ID: <54CA6327.5070707@free.fr> (raw)
In-Reply-To: <54B7F7CD.7030903@free.fr>
[-- Attachment #1: Type: text/plain, Size: 736 bytes --]
On 15/01/2015 18:24, Mason wrote:
> This is a follow-up to my previous thread.
> "How many frequencies would cpufreq optimally like to manage?"
> http://thread.gmane.org/gmane.linux.ports.arm.kernel/373669
OK, so this is my TAKE 2 on the cpufreq driver, trying to remove
some dependencies on machine-specific definitions by getting the
virtual address at init via ioremap. (Is -EFAULT the right error
to return if ioremap fails?)
I'm not sure where machine-specific information is supposed to
be stored though? Such as register definitions, or the physical
addresses/offsets. What if they need to be shared among several
source files? I can't just duplicate them... (I've tentatively
called it temp.h for the time being.)
Regards.
[-- Attachment #2: cpufreq.c --]
[-- Type: text/x-csrc, Size: 2567 bytes --]
/*
* Copyright 2015 Sigma Designs
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
*/
#include <linux/module.h>
#include <linux/cpufreq.h>
#include <linux/io.h>
#include "temp.h"
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Sigma Designs");
MODULE_DESCRIPTION("cpufreq driver for Tangox 87xx");
#define TANGOX_XTAL_FREQ 27000 /* in kHz */
#define CLKGEN_BASE 0x10000
#define SYS_clkgen0_pll (clkgen_base + 0x00)
#define SYS_cpuclk_div_ctrl (clkgen_base + 0x24)
static void __iomem *clkgen_base;
static struct cpufreq_frequency_table freq_table[] = {
{ .driver_data = 1 },
{ .driver_data = 2 },
{ .driver_data = 3 },
{ .driver_data = 5 },
{ .driver_data = 9 },
{ .frequency = CPUFREQ_TABLE_END },
};
static unsigned int tangox_get_freq(unsigned int cpu)
{
union SYS_clkgen_pll pll;
union SYS_clk_div_ctrl div;
pll.val = readl_relaxed(SYS_clkgen0_pll);
if (pll.f.Isel != 1 || pll.f.M != 0) return 0;
div.val = readl_relaxed(SYS_cpuclk_div_ctrl);
if (div.f.BP != 0 || div.f.F != 0) return 0;
return TANGOX_XTAL_FREQ * (pll.f.N + 1) / div.f.I >> pll.f.K;
}
static int tangox_target(struct cpufreq_policy *policy, unsigned int index)
{
while (readl_relaxed(SYS_cpuclk_div_ctrl) >> 31) cpu_relax();
writel_relaxed(freq_table[index].driver_data, SYS_cpuclk_div_ctrl);
return 0;
}
static int tangox_cpu_init(struct cpufreq_policy *policy)
{
struct cpufreq_frequency_table *p;
unsigned int freq = tangox_get_freq(0);
unsigned int transition_latency_ns = freq / SYS_FAST_RAMP_SPEED;
if ((clkgen_base = ioremap(CLKGEN_BASE, 0x40)) == NULL) return -EFAULT;
for (p = freq_table; p->frequency != CPUFREQ_TABLE_END; ++p) {
unsigned int I = p->driver_data;
union SYS_clk_div_ctrl div = SYS_CLK_DIV_CTRL(I);
p->driver_data = div.val;
p->frequency = freq / I;
}
return cpufreq_generic_init(policy, freq_table, transition_latency_ns);
}
static struct cpufreq_driver tangox_cpufreq_driver = {
.name = "tangox-cpufreq",
.init = tangox_cpu_init,
.verify = cpufreq_generic_frequency_table_verify,
.target_index = tangox_target,
.get = tangox_get_freq,
.exit = cpufreq_generic_exit,
.attr = cpufreq_generic_attr,
};
static int __init tangox_cpufreq_init(void)
{
return cpufreq_register_driver(&tangox_cpufreq_driver);
}
static void __exit tangox_cpufreq_exit(void)
{
cpufreq_unregister_driver(&tangox_cpufreq_driver);
}
module_init(tangox_cpufreq_init);
module_exit(tangox_cpufreq_exit);
next prev parent reply other threads:[~2015-01-29 16:43 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-15 17:24 RFC on cpufreq implementation Mason
2015-01-16 9:08 ` Krzysztof Kozlowski
2015-01-16 11:10 ` Mason
2015-01-16 11:43 ` Krzysztof Kozlowski
2015-01-16 12:10 ` Javi Merino
2015-01-16 14:00 ` Mason
2015-01-19 7:52 ` Viresh Kumar
2015-01-19 22:03 ` Mason
2015-01-20 3:55 ` Viresh Kumar
2015-01-19 9:22 ` Amit Kucheria
2015-01-19 22:13 ` Mason
2015-01-29 16:43 ` Mason [this message]
2015-01-30 1:15 ` Viresh Kumar
2015-01-30 23:44 ` Mason
2015-02-02 3:58 ` Viresh Kumar
2015-02-04 0:07 ` Mason
2015-02-04 0:32 ` Måns Rullgård
2015-02-04 4:12 ` Viresh Kumar
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=54CA6327.5070707@free.fr \
--to=mpeg.blue@free.fr \
--cc=cpufreq@vger.kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-pm@vger.kernel.org \
--cc=rjw@rjwysocki.net \
--cc=viresh.kumar@linaro.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox