All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tuomas Tynkkynen <ttynkkynen@nvidia.com>
To: Mark Brown <broonie@kernel.org>,
	Thierry Reding <thierry.reding@gmail.com>
Cc: Andrew Bresticker <abrestic@chromium.org>,
	"linux-tegra@vger.kernel.org" <linux-tegra@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	"linux-pm@vger.kernel.org" <linux-pm@vger.kernel.org>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	Prashant Gaikwad <pgaikwad@nvidia.com>,
	Mike Turquette <mturquette@linaro.org>,
	Stephen Warren <swarren@wwwdotorg.org>,
	Viresh Kumar <viresh.kumar@linaro.org>,
	Peter De Schrijver <pdeschrijver@nvidia.com>,
	"Rafael J. Wysocki" <rjw@rjwysocki.net>
Subject: Re: [PATCH 01/13] clk: tegra: Add binding for the Tegra124 DFLL clocksource
Date: Tue, 15 Jul 2014 23:23:39 +0300	[thread overview]
Message-ID: <53C58DCB.90502@nvidia.com> (raw)
In-Reply-To: <20140714102203.GD6800@sirena.org.uk>

On 14/07/14 13:22, Mark Brown wrote:
> * PGP Signed by an unknown key
> 
> On Mon, Jul 14, 2014 at 11:24:35AM +0200, Thierry Reding wrote:
>> On Mon, Jul 14, 2014 at 10:12:33AM +0100, Mark Brown wrote:
> 
>>> The selector value is opaque, it's entirely up to the driver to define
>>> it.  If you could tell me what "this" is I might be able to advise on
>>> how to do it.
> 
>> Tegra124 (and later, also some earlier variants) have this DFLL clock
>> that can program a PMIC automatically depending on the CPU frequency.
>> This DT binding did propose putting this into device tree as a table of
>> <frequency value> pairs where the frequency corresponds to the CPU
>> frequency and the value is the register value to be programmed into the
>> PMIC by the DFLL hardware (there are two additional properties to define
>> the slave address and the register offset).
> 
>> Andrew proposed that this table could instead be built by using
>> regulator_list_voltage() instead. However, due to the fact that the DFLL
>> hardware needs to know the immediate value to write into a register, the
>> requirement would be for a 1:1 mapping between selector and register
>> value. Given that the API needs to cover the general case I don't see
>> how it could practically ensure this.
> 
> Well, if you're going to do that you've already created a private API
> between the regulator driver and the device since you're assuming that
> the device is controlled only by register writes to a single register
> bitfield which isn't always the case.
> 
> As with all these things it would also be better to extend the regulator
> API so that users like this can discover the register address and so on
> too rather than having to replicate that information in the device tree.
> No sense in having to specify this information multiple times.
> 

That sounds indeed useful for this case. How'd the following interface
sound for the register offset / selector-to-register-value conversion?
The I2C address would be a bit trickier to get as it would touch the
regmap stuff as well, but perhaps it would be a good idea to have a
phandle to the I2C device itself, and then parse the reg field for
the address.

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c563d93..a5efb96 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2228,6 +2228,63 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
 EXPORT_SYMBOL_GPL(regulator_list_voltage);

 /**
+ * regulator_get_hardware_vsel_register - get the HW voltage selector register
+ * @regulator: regulator source
+ * @vsel_reg: voltage selector register, output parameter
+ * @vsel_mask: mask for voltage selector bitfield, output parameter
+ *
+ * Returns the hardware register offset and bitmask used for setting the
+ * regulator voltage. This might be useful when configuring voltage-scaling
+ * hardware or firmware that can make I2C requests behind the kernel's back,
+ * for example.
+ *
+ * On success, the output parameters @vsel_reg and @vsel_mask are filled in
+ * and 0 is returned, otherwise a negative errno is returned.
+ */
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+
+	if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+		return -EOPNOTSUPP;
+
+	 *vsel_reg = rdev->desc->vsel_reg;
+	 *vsel_mask = rdev->desc->vsel_mask;
+
+	 return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register);
+
+/**
+ * regulator_list_hardware_vsel - get the HW-specific register value for a selector
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ *
+ * Converts the selector to a hardware-specific voltage selector that can be
+ * directly written to the regulator registers. The address of the voltage
+ * register can be determined by calling @regulator_get_hardware_vsel_register.
+ *
+ * On error a negative errno is returned.
+ */
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+	if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+		return -EOPNOTSUPP;
+
+	return selector;
+}
+EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel);
+
+/**
  * regulator_get_linear_step - return the voltage step size between VSEL values
  * @regulator: regulator source
  *
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 14ec18d..fe4cdb2 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -215,6 +215,12 @@ int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);

 int regulator_allow_bypass(struct regulator *regulator, bool allow);

+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask);
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector);
+
 /* regulator notifier block */
 int regulator_register_notifier(struct regulator *regulator,
 			      struct notifier_block *nb);

-- 
nvpublic

WARNING: multiple messages have this Message-ID (diff)
From: ttynkkynen@nvidia.com (Tuomas Tynkkynen)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 01/13] clk: tegra: Add binding for the Tegra124 DFLL clocksource
Date: Tue, 15 Jul 2014 23:23:39 +0300	[thread overview]
Message-ID: <53C58DCB.90502@nvidia.com> (raw)
In-Reply-To: <20140714102203.GD6800@sirena.org.uk>

On 14/07/14 13:22, Mark Brown wrote:
> * PGP Signed by an unknown key
> 
> On Mon, Jul 14, 2014 at 11:24:35AM +0200, Thierry Reding wrote:
>> On Mon, Jul 14, 2014 at 10:12:33AM +0100, Mark Brown wrote:
> 
>>> The selector value is opaque, it's entirely up to the driver to define
>>> it.  If you could tell me what "this" is I might be able to advise on
>>> how to do it.
> 
>> Tegra124 (and later, also some earlier variants) have this DFLL clock
>> that can program a PMIC automatically depending on the CPU frequency.
>> This DT binding did propose putting this into device tree as a table of
>> <frequency value> pairs where the frequency corresponds to the CPU
>> frequency and the value is the register value to be programmed into the
>> PMIC by the DFLL hardware (there are two additional properties to define
>> the slave address and the register offset).
> 
>> Andrew proposed that this table could instead be built by using
>> regulator_list_voltage() instead. However, due to the fact that the DFLL
>> hardware needs to know the immediate value to write into a register, the
>> requirement would be for a 1:1 mapping between selector and register
>> value. Given that the API needs to cover the general case I don't see
>> how it could practically ensure this.
> 
> Well, if you're going to do that you've already created a private API
> between the regulator driver and the device since you're assuming that
> the device is controlled only by register writes to a single register
> bitfield which isn't always the case.
> 
> As with all these things it would also be better to extend the regulator
> API so that users like this can discover the register address and so on
> too rather than having to replicate that information in the device tree.
> No sense in having to specify this information multiple times.
> 

That sounds indeed useful for this case. How'd the following interface
sound for the register offset / selector-to-register-value conversion?
The I2C address would be a bit trickier to get as it would touch the
regmap stuff as well, but perhaps it would be a good idea to have a
phandle to the I2C device itself, and then parse the reg field for
the address.

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index c563d93..a5efb96 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -2228,6 +2228,63 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector)
 EXPORT_SYMBOL_GPL(regulator_list_voltage);

 /**
+ * regulator_get_hardware_vsel_register - get the HW voltage selector register
+ * @regulator: regulator source
+ * @vsel_reg: voltage selector register, output parameter
+ * @vsel_mask: mask for voltage selector bitfield, output parameter
+ *
+ * Returns the hardware register offset and bitmask used for setting the
+ * regulator voltage. This might be useful when configuring voltage-scaling
+ * hardware or firmware that can make I2C requests behind the kernel's back,
+ * for example.
+ *
+ * On success, the output parameters @vsel_reg and @vsel_mask are filled in
+ * and 0 is returned, otherwise a negative errno is returned.
+ */
+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+
+	if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+		return -EOPNOTSUPP;
+
+	 *vsel_reg = rdev->desc->vsel_reg;
+	 *vsel_mask = rdev->desc->vsel_mask;
+
+	 return 0;
+}
+EXPORT_SYMBOL_GPL(regulator_get_hardware_vsel_register);
+
+/**
+ * regulator_list_hardware_vsel - get the HW-specific register value for a selector
+ * @regulator: regulator source
+ * @selector: identify voltage to list
+ *
+ * Converts the selector to a hardware-specific voltage selector that can be
+ * directly written to the regulator registers. The address of the voltage
+ * register can be determined by calling @regulator_get_hardware_vsel_register.
+ *
+ * On error a negative errno is returned.
+ */
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector)
+{
+	struct regulator_dev	*rdev = regulator->rdev;
+	struct regulator_ops	*ops = rdev->desc->ops;
+
+	if (selector >= rdev->desc->n_voltages)
+		return -EINVAL;
+	if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap)
+		return -EOPNOTSUPP;
+
+	return selector;
+}
+EXPORT_SYMBOL_GPL(regulator_list_hardware_vsel);
+
+/**
  * regulator_get_linear_step - return the voltage step size between VSEL values
  * @regulator: regulator source
  *
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h
index 14ec18d..fe4cdb2 100644
--- a/include/linux/regulator/consumer.h
+++ b/include/linux/regulator/consumer.h
@@ -215,6 +215,12 @@ int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);

 int regulator_allow_bypass(struct regulator *regulator, bool allow);

+int regulator_get_hardware_vsel_register(struct regulator *regulator,
+					 unsigned *vsel_reg,
+					 unsigned *vsel_mask);
+int regulator_list_hardware_vsel(struct regulator *regulator,
+				 unsigned selector);
+
 /* regulator notifier block */
 int regulator_register_notifier(struct regulator *regulator,
 			      struct notifier_block *nb);

-- 
nvpublic

  reply	other threads:[~2014-07-15 20:23 UTC|newest]

Thread overview: 106+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-10 21:42 [PATCH 00/13] Tegra124 CL-DVFS / DFLL clocksource, plus cpufreq Tuomas Tynkkynen
2014-07-10 21:42 ` Tuomas Tynkkynen
2014-07-10 21:42 ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 01/13] clk: tegra: Add binding for the Tegra124 DFLL clocksource Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-11 16:28   ` Andrew Bresticker
2014-07-11 16:28     ` Andrew Bresticker
     [not found]     ` <CAL1qeaFF0ZpUFovxTuLXrBPRg2Lbf-754Z=ztD5HFZPbfnDsAw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-07-11 16:48       ` Tuomas Tynkkynen
2014-07-11 16:48         ` Tuomas Tynkkynen
2014-07-11 16:48         ` Tuomas Tynkkynen
2014-07-11 17:08         ` Andrew Bresticker
2014-07-11 17:08           ` Andrew Bresticker
     [not found]           ` <CAL1qeaHETQ7kSGNjPiwi_9WNMtr9qZp0KwjZCCxY29+_N4AcuA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-07-11 17:21             ` Tuomas Tynkkynen
2014-07-11 17:21               ` Tuomas Tynkkynen
2014-07-11 17:21               ` Tuomas Tynkkynen
2014-07-14  8:38               ` Thierry Reding
2014-07-14  8:38                 ` Thierry Reding
2014-07-14  9:12                 ` Mark Brown
2014-07-14  9:12                   ` Mark Brown
2014-07-14  9:12                   ` Mark Brown
     [not found]                   ` <20140714091233.GC6800-GFdadSzt00ze9xe1eoZjHA@public.gmane.org>
2014-07-14  9:24                     ` Thierry Reding
2014-07-14  9:24                       ` Thierry Reding
2014-07-14  9:24                       ` Thierry Reding
2014-07-14 10:22                       ` Mark Brown
2014-07-14 10:22                         ` Mark Brown
2014-07-14 10:22                         ` Mark Brown
2014-07-15 20:23                         ` Tuomas Tynkkynen [this message]
2014-07-15 20:23                           ` Tuomas Tynkkynen
     [not found]                           ` <53C58DCB.90502-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-07-15 22:52                             ` Mark Brown
2014-07-15 22:52                               ` Mark Brown
2014-07-15 22:52                               ` Mark Brown
2014-07-16  8:01                               ` Thierry Reding
2014-07-16  8:01                                 ` Thierry Reding
2014-07-16 11:00                                 ` Mark Brown
2014-07-16 11:00                                   ` Mark Brown
2014-07-16 11:00                                   ` Mark Brown
2014-07-10 21:42 ` [PATCH 02/13] clk: tegra: Add library for the DFLL clock source (open-loop mode) Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 03/13] clk: tegra: Add closed loop support for the DFLL Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 04/13] clk: tegra: Add functions for parsing CVB tables Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 05/13] clk: tegra: Add DFLL DVCO reset control for Tegra124 Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 06/13] clk: tegra: Add Tegra124 DFLL clocksource platform driver Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 07/13] clk: tegra: Save/restore CCLKG_BURST_POLICY on suspend Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 08/13] clk: tegra: Add the DFLL as a possible parent of the cclk_g clock Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 09/13] ARM: tegra: Add the DFLL to Tegra124 device tree Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 11/13] cpufreq: tegra124: Add device tree bindings Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42 ` [PATCH 13/13] ARM: tegra: Add entries for cpufreq on Tegra124 Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
2014-07-10 21:42   ` Tuomas Tynkkynen
     [not found] ` <1405028569-14253-1-git-send-email-ttynkkynen-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-07-10 21:42   ` [PATCH 10/13] ARM: tegra: Enable the DFLL on the Jetson TK1 Tuomas Tynkkynen
2014-07-10 21:42     ` Tuomas Tynkkynen
2014-07-10 21:42     ` Tuomas Tynkkynen
2014-07-11  7:14     ` Mikko Perttunen
2014-07-11  7:14       ` Mikko Perttunen
2014-07-10 21:42   ` [PATCH 12/13] cpufreq: Add cpufreq driver for Tegra124 Tuomas Tynkkynen
2014-07-10 21:42     ` Tuomas Tynkkynen
2014-07-10 21:42     ` Tuomas Tynkkynen
     [not found]     ` <1405028569-14253-13-git-send-email-ttynkkynen-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-07-11  4:35       ` Viresh Kumar
2014-07-11  4:35         ` Viresh Kumar
2014-07-11  4:35         ` Viresh Kumar
     [not found]         ` <CAKohpom9ORXFiUU4=V+CxgN0ZOFLMEhEjHiU8HsYUYDybNXgHQ-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-07-11  9:12           ` Peter De Schrijver
2014-07-11  9:12             ` Peter De Schrijver
2014-07-11  9:12             ` Peter De Schrijver
2014-07-11  9:14             ` Viresh Kumar
2014-07-11  9:14               ` Viresh Kumar
     [not found]             ` <20140711091207.GY23218-Rysk9IDjsxmJz7etNGeUX8VPkgjIgRvpAL8bYrjMMd8@public.gmane.org>
2014-07-11 14:57               ` Thierry Reding
2014-07-11 14:57                 ` Thierry Reding
2014-07-11 14:57                 ` Thierry Reding
2014-07-11 15:11                 ` Tuomas Tynkkynen
2014-07-11 15:11                   ` Tuomas Tynkkynen
2014-07-11 15:11                   ` Tuomas Tynkkynen
2014-07-11 15:15                   ` Thierry Reding
2014-07-11 15:15                     ` Thierry Reding
2014-07-11 15:29                     ` Tuomas Tynkkynen
2014-07-11 15:29                       ` Tuomas Tynkkynen
2014-07-11 15:29                       ` Tuomas Tynkkynen
     [not found]                       ` <53C002BE.90805-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-07-11 16:33                         ` Andrew Bresticker
2014-07-11 16:33                           ` Andrew Bresticker
2014-07-11 16:33                           ` Andrew Bresticker
2014-07-11 14:14           ` Tuomas Tynkkynen
2014-07-11 14:14             ` Tuomas Tynkkynen
2014-07-11 14:14             ` Tuomas Tynkkynen
     [not found]             ` <53BFF132.3020700-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
2014-07-11 14:37               ` Viresh Kumar
2014-07-11 14:37                 ` Viresh Kumar
2014-07-11 14:37                 ` Viresh Kumar
2014-07-11 15:32   ` [PATCH 00/13] Tegra124 CL-DVFS / DFLL clocksource, plus cpufreq Mike Turquette
2014-07-11 15:32     ` Mike Turquette
2014-07-11 15:32     ` Mike Turquette

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=53C58DCB.90502@nvidia.com \
    --to=ttynkkynen@nvidia.com \
    --cc=abrestic@chromium.org \
    --cc=broonie@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=linux-tegra@vger.kernel.org \
    --cc=mturquette@linaro.org \
    --cc=pdeschrijver@nvidia.com \
    --cc=pgaikwad@nvidia.com \
    --cc=rjw@rjwysocki.net \
    --cc=swarren@wwwdotorg.org \
    --cc=thierry.reding@gmail.com \
    --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.