All of lore.kernel.org
 help / color / mirror / Atom feed
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

WARNING: multiple messages have this Message-ID (diff)
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

WARNING: multiple messages have this Message-ID (diff)
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

  reply	other threads:[~2013-06-20 21:43 UTC|newest]

Thread overview: 12+ 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 19:17 ` Nishanth Menon
2013-06-19 22:38 ` Mark Brown
2013-06-20 12:45   ` Nishanth Menon
2013-06-20 12:45     ` Nishanth Menon
2013-06-20 21:43     ` Nishanth Menon [this message]
2013-06-20 21:43       ` Nishanth Menon
2013-06-20 21:43       ` Nishanth Menon
2013-06-21  9:51     ` Mark Brown
2013-06-21 12:43       ` Nishanth Menon
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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.