From: Nishanth Menon <nm@ti.com>
To: Mark Brown <broonie@kernel.org>
Cc: Liam Girdwood <lgirdwood@gmail.com>,
<linux-kernel@vger.kernel.org>, <linux-omap@vger.kernel.org>,
<viresh.kumar@linaro.org>, <cpufreq@vger.kernel.org>
Subject: Re: [RFC PATCH] regulator: core: allow consumers to request to closes step voltage
Date: Thu, 20 Jun 2013 16:43:45 -0500 [thread overview]
Message-ID: <20130620214344.GA10756@kahuna> (raw)
In-Reply-To: <20130620124542.GA28320@kahuna>
On 07:45-20130620, Nishanth Menon wrote:
> On 23:38-20130619, Mark Brown wrote:
> > On Wed, Jun 19, 2013 at 02:17:54PM -0500, Nishanth Menon wrote:
> >
> > > Account for step size accuracy when exact voltage requests are send for
> > > step based regulators.
> >
> > If the consumer can tolerate a different voltage why not just request
> > the range that can be tolerated? Your problem here is specifying an
> > exact voltage.
> I think you mean using regulator_get_linear_step
>
> >
> > > The specific example I faced was using cpufreq-cpu0 driver with voltages
> > > for OPPs for MPU rail and attempting the common definitions against voltages
> > > that are non-exact multiples of stepsize of PMIC.
> >
> > > The alternative would be implement custom set_voltage (as againsta simpler
> > > set_voltage_sel and using linear map/list functions) for the regulator which
> > > will account for the same.
> >
> > > Yet another alternative might be to introduce yet another custom function similar
> > > to regulator_set_voltage_tol which accounts for this. something like:
> > > regulator_set_voltage_floor(regulator, voltage, tol) or something to that effect.
> >
> > Or as I keep telling you guys the consumer can just do that directly
> > using the existing API; the whole point in specifying the voltage as a
> > range is to allow the consumer to cope with arbatrary regulators by
> > giving a range of voltages that it can accept.
> >
> > The API is deliberately very conservative in these matters since there
> > is a danger of physical damage if things really go wrong in some
> > applications, it makes sure that both the drivers and the system
> > integration are involved.
> I agree. The intent of this series was to start a conversation to see if
> we can make it simpler.
>
> Searching for the users of regulator_get_linear_step in 3.10-rc6
> shows none.
>
> For a generic driver which needs to handle platforms which
> have tolerance, they'd use regulator_set_voltage_tol. But the
> implementation would allow for uV - tol to uV + tol as range, which in
> the case I mentioned(min voltage =uV) wont work.
>
> If the consumer wants to be aware of linear step regulator, they'd have to do:
> step_uV = regulator_get_linear_step(...);
> regulator_set_voltage(uV, uV + step_uV);
>
> Then this wont handle tolerance. So the solution seems to be (for the
> consumer):
> step_uV = regulator_get_linear_step(...);
> ..
> if (tol)
> regulator_set_voltage_tol(uV, tol);
> else
> regulator_set_voltage(uV, uV + step_uV);
> (with the required error checks for regulator being a linear regulator
> etc..).
>
> At least to me, there is no sane manner to handle "tolerance" and linear step
> accuracy for a defined voltage (Should tolerance be rounded off to
> step_uV? what about the border cases etc.)
>
> Would you agree?
Here is an RFC for the same. My hope was to see if something simpler
could be done.
>From cb9830191cb9b8021e50bcda25d110b4b9a7dbd3 Mon Sep 17 00:00:00 2001
From: Nishanth Menon <nm@ti.com>
Date: Thu, 20 Jun 2013 16:37:30 -0500
Subject: [RFC PATCH] cpufreq: cpufreq-cpu0: account for regulator step size
accuracy
Generic regulator consumers such as cpufreq-cpu0 are not aware
of the characteristics of regulator used to supply. For example:
consumerX requests for voltage min_uV = 500mV, max_uV = 500mV
On a regulator which has a step size of 10mV, this can be exactly
achieved.
However, on a regulator which is non-exact divider step size (example
12.66mV step size), the closest achievable would be 506.4.
regulator_set_voltage_tol does not work out either as <500mV is not an
acceptable operational voltage.
Account for step size accuracy when exact voltage requests are send for
step based regulators.
Signed-off-by: Nishanth Menon <nm@ti.com>
---
drivers/cpufreq/cpufreq-cpu0.c | 28 ++++++++++++++++++++++++----
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/cpufreq/cpufreq-cpu0.c b/drivers/cpufreq/cpufreq-cpu0.c
index ad1fde2..707565c 100644
--- a/drivers/cpufreq/cpufreq-cpu0.c
+++ b/drivers/cpufreq/cpufreq-cpu0.c
@@ -28,6 +28,7 @@ static struct device *cpu_dev;
static struct clk *cpu_clk;
static struct regulator *cpu_reg;
static struct cpufreq_frequency_table *freq_table;
+static int cpu_reg_step_size;
static int cpu0_verify_speed(struct cpufreq_policy *policy)
{
@@ -91,7 +92,12 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
/* scaling up? scale voltage before frequency */
if (cpu_reg && freqs.new > freqs.old) {
- ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
+ if (tol)
+ ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
+ else
+ ret = regulator_set_voltage(cpu_reg, volt,
+ volt + cpu_reg_step_size);
+
if (ret) {
pr_err("failed to scale voltage up: %d\n", ret);
freqs.new = freqs.old;
@@ -102,15 +108,28 @@ static int cpu0_set_target(struct cpufreq_policy *policy,
ret = clk_set_rate(cpu_clk, freq_exact);
if (ret) {
pr_err("failed to set clock rate: %d\n", ret);
- if (cpu_reg)
- regulator_set_voltage_tol(cpu_reg, volt_old, tol);
+ if (cpu_reg) {
+ if (tol)
+ ret = regulator_set_voltage_tol(cpu_reg,
+ volt_old,
+ tol);
+ else
+ ret = regulator_set_voltage(cpu_reg,
+ volt_old,
+ volt_old +
+ cpu_reg_step_size);
+ }
freqs.new = freqs.old;
goto post_notify;
}
/* scaling down? scale voltage after frequency */
if (cpu_reg && freqs.new < freqs.old) {
- ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
+ if (tol)
+ ret = regulator_set_voltage_tol(cpu_reg, volt, tol);
+ else
+ ret = regulator_set_voltage(cpu_reg, volt,
+ volt + cpu_reg_step_size);
if (ret) {
pr_err("failed to scale voltage down: %d\n", ret);
clk_set_rate(cpu_clk, freqs.old * 1000);
@@ -260,6 +279,7 @@ static int cpu0_cpufreq_probe(struct platform_device *pdev)
ret = regulator_set_voltage_time(cpu_reg, min_uV, max_uV);
if (ret > 0)
transition_latency += ret * 1000;
+ cpu_reg_step_size = regulator_get_linear_step(cpu_reg);
}
ret = cpufreq_register_driver(&cpu0_cpufreq_driver);
--
1.7.9.5
--
Regards,
Nishanth Menon
next prev parent reply other threads:[~2013-06-20 21:43 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-06-19 19:17 [RFC PATCH] regulator: core: allow consumers to request to closes step voltage Nishanth Menon
2013-06-19 22:38 ` Mark Brown
2013-06-20 12:45 ` Nishanth Menon
2013-06-20 21:43 ` Nishanth Menon [this message]
2013-06-21 9:51 ` Mark Brown
2013-06-21 12:43 ` Nishanth Menon
2013-06-21 14:30 ` Mark Brown
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=20130620214344.GA10756@kahuna \
--to=nm@ti.com \
--cc=broonie@kernel.org \
--cc=cpufreq@vger.kernel.org \
--cc=lgirdwood@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--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