2008-03-06 18:11:49

by Liam Girdwood

[permalink] [raw]
Subject: [UPDATED v3][PATCH 1/7] regulator: consumer interface

The regulator framework provides voltage and current power control to
consumer drivers. This allows consumers to control their supply voltages and
current levels.

The framework is similar to the kernel clock interface in that client or
consumer drivers can get() and put() a regulator (like they can with clocks
atm).

Consumers can also get() or set() :- voltage, current, operating mode.
Consumers can also enable and disable regulators.

The framework also compiles out if not in use so drivers can be reused in
systems with no software PMIC power control.

Signed-off-by: Liam Girdwood <[email protected]>
---
include/linux/regulator/regulator.h | 264 +++++++++++++++++++++++++++++++++++
1 files changed, 264 insertions(+), 0 deletions(-)
create mode 100644 include/linux/regulator/regulator.h

diff --git a/include/linux/regulator/regulator.h b/include/linux/regulator/regulator.h
new file mode 100644
index 0000000..13a93e9
--- /dev/null
+++ b/include/linux/regulator/regulator.h
@@ -0,0 +1,264 @@
+/*
+ * regulator.h -- SoC Regulator support.
+ *
+ * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
+ *
+ * Author: Liam Girdwood <[email protected]>
+ *
+ * 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.
+ *
+ * Regulator Client Interface.
+ *
+ * A Power Management Regulator framework for SoC based devices.
+ * Features:-
+ * o Voltage and current level control.
+ * o Operating mode control.
+ * o Regulator status.
+ * o sysfs entries for showing client devices and status
+ *
+ * EXPERIMENTAL FEATURES:
+ * Dynamic Regulator operating Mode Switching (DRMS) - allows regulators
+ * to use most efficient operating mode depending upon voltage and load and
+ * is transparent to client drivers.
+ *
+ * e.g. Devices x,y,z share regulator r. Device x and y draw 20mA each during
+ * IO and 1mA at idle. Device z draws 100mA when under load and 5mA when
+ * idling. Regulator r has > 90% efficiency in NORMAL mode at loads > 100mA
+ * but this drops rapidly to 60% when below 100mA. Regulator r has > 90%
+ * efficiency in IDLE mode at loads < 10mA. Thus regulator r will operate
+ * in normal mode for loads > 10mA and in IDLE mode for load <= 10mA.
+ *
+ * Dynamic Regulator Voltage Selection (DRVS). Selects the lowest voltage
+ * output (within system constraints) for a regulator shared between several
+ * devices. This allows all devices to operate within their voltage range and
+ * will dynamically change the voltage when devices disable() their supply
+ * to the next best level (thus saving power). This is based on an idea
+ * by Amit Kucheria in an RFC to lakml.
+ *
+ * e.g. devices x,y,z share regulator r. device x and y can operate between
+ * 1800mV and 1900mV, whilst device z can only operate at 1900mV. Regulator
+ * r will output 1900mV when all devices are in use and 1800mV when devices
+ * x and y are in use and device z is disabled.
+ */
+
+#ifndef __LINUX_REGULATOR_H_
+#define __LINUX_REGULATOR_H_
+
+/*
+ * Regulator operating modes.
+ *
+ * Regulators can run in a variety of different operating modes depending on
+ * output load. This allows further system power savings by selecting the
+ * best (and most efficient) regulator mode for a desired load.
+ *
+ * Most drivers will only care about NORMAL. The modes below are generic and
+ * will probably not match the naming convention of your regulator data sheet
+ * but should match the use cases in the datasheet.
+ *
+ * In order of power efficiency (least efficient at top).
+ *
+ * Mode Description
+ * FAST Regulator can handle fast changes in it's load.
+ * e.g. useful in CPU voltage & frequency scaling where
+ * load can quickly increase with CPU frequency increases.
+ *
+ * NORMAL Normal regulator power supply mode. Most drivers will
+ * use this mode.
+ *
+ * IDLE Regulator runs in a more efficient mode for light
+ * loads. Can be used for devices that have a low power
+ * requirement during periods of inactivity. This mode
+ * may be more noisy than NORMAL and may not be able
+ * to handle fast load switching.
+ *
+ * STANDBY Regulator runs in the most efficient mode for very
+ * light loads. Can be used by devices when they are
+ * in a sleep/standby state. This mode is likely to be
+ * the most noisy and may not be able to handle fast load
+ * switching.
+ *
+ * NOTE: Most regulators will only support a subset of these modes. Some
+ * will only just support NORMAL.
+ *
+ * These modes can be OR'ed together to make up a mask of valid register modes.
+ */
+
+#define REGULATOR_MODE_FAST 0x1
+#define REGULATOR_MODE_NORMAL 0x2
+#define REGULATOR_MODE_IDLE 0x4
+#define REGULATOR_MODE_STANDBY 0x8
+
+/*
+ * Regulator notifier events.
+ *
+ * UNDER_VOLTAGE Regulator output is under voltage.
+ * OVER_CURRENT Regulator output current is too high.
+ * POWER_ON Regulator power ON event.
+ * POWER_OFF Regulator power OFF event.
+ * REGULATION_OUT Regulator output is out of regulation.
+ * FAIL Regulator output has failed.
+ * OVER_TEMP Regulator over temp.
+ *
+ * NOTE: These events can be OR'ed together when passed into handler.
+ */
+
+#define REGULATOR_EVENT_UNDER_VOLTAGE 0x1
+#define REGULATOR_EVENT_OVER_CURRENT 0x2
+#define REGULATOR_EVENT_POWER_ON 0x4
+#define REGULATOR_EVENT_POWER_OFF 0x8
+#define REGULATOR_EVENT_REGULATION_OUT 0x10
+#define REGULATOR_EVENT_FAIL 0x20
+#define REGULATOR_EVENT_OVER_TEMP 0x40
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+static inline int mV_to_uV(int mV) { return mV * 1000; }
+static inline int uV_to_mV(int uV) { return uV / 1000; }
+static inline int V_to_uV(int V) { return V * 1000000; }
+static inline int uV_to_V(int uV) { return uV / 1000000; }
+static inline int mA_to_uA(int mA) { return mA * 1000; }
+static inline int uA_to_mA(int uA) {return uA / 1000; }
+static inline int A_to_uA(int A) { return A * 1000000; }
+static inline int uA_to_A(int uA) { return uA / 1000000; }
+
+struct regulator;
+
+#if defined(CONFIG_REGULATOR)
+
+/* regulator get and put */
+struct regulator *__must_check regulator_get(struct device *dev,
+ const char *id);
+void regulator_put(struct regulator *regulator);
+
+/* regulator output control and status */
+int regulator_enable(struct regulator *regulator);
+int regulator_disable(struct regulator *regulator);
+int regulator_is_enabled(struct regulator *regulator);
+
+int regulator_set_voltage(struct regulator *regulator, int uV);
+int regulator_get_voltage(struct regulator *regulator);
+int regulator_set_current(struct regulator *regulator, int uA);
+int regulator_get_current(struct regulator *regulator);
+
+int regulator_set_mode(struct regulator *regulator, unsigned int mode);
+unsigned int regulator_get_mode(struct regulator *regulator);
+unsigned int regulator_get_optimum_mode(struct regulator *regulator,
+ int input_uV, int output_uV,
+ int load_uA);
+
+/* regulator notifier block */
+int regulator_register_client(struct regulator *regulator,
+ struct notifier_block *nb);
+int regulator_unregister_client(struct regulator *regulator,
+ struct notifier_block *nb);
+
+/* notify core of likely current draw */
+void regulator_drms_notify_load(struct regulator *regulator, int uA);
+
+/* driver data - core doesn't touch */
+void *regulator_get_drvdata(struct regulator *regulator);
+void regulator_set_drvdata(struct regulator *regulator, void *data);
+
+#else
+
+/*
+ * Make sure client drivers will still build on systems with no software
+ * controllable voltage or current regulators.
+ */
+static inline struct regulator *__must_check regulator_get(struct device *dev,
+ const char *id)
+{
+ return NULL;
+}
+static inline void regulator_put(struct regulator *regulator)
+{
+}
+
+static inline int regulator_enable(struct regulator *regulator)
+{
+ return 0;
+}
+
+static inline int regulator_disable(struct regulator *regulator)
+{
+ return 0;
+}
+
+static inline int regulator_is_enabled(struct regulator *regulator)
+{
+ return 1;
+}
+
+static inline int regulator_set_voltage(struct regulator *regulator, int uV)
+{
+ return 0;
+}
+
+static inline int regulator_get_voltage(struct regulator *regulator)
+{
+ return 0;
+}
+
+static inline int regulator_set_current(struct regulator *regulator, int uA)
+{
+ return 0;
+}
+
+static inline int regulator_get_current(struct regulator *regulator)
+{
+ return 0;
+}
+
+static inline int regulator_set_mode(struct regulator *regulator,
+ unsigned int mode)
+{
+ return 0;
+}
+
+static inline unsigned int regulator_get_mode(struct regulator *regulator)
+{
+ return REGULATOR_MODE_NORMAL;
+}
+
+static inline unsigned int regulator_get_optimum_mode(
+ struct regulator *regulator,
+ int input_uV, int output_uV,
+ int load_uA)
+{
+ return REGULATOR_MODE_NORMAL;
+}
+
+static inline int regulator_register_client(struct regulator *regulator,
+ struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline int regulator_unregister_client(struct regulator *regulator,
+ struct notifier_block *nb)
+{
+ return 0;
+}
+
+static inline void regulator_drms_notify_load(struct regulator *regulator,
+ int uA)
+{
+}
+
+static inline void *regulator_get_drvdata(struct regulator *regulator)
+{
+ return NULL;
+}
+
+static inline void regulator_set_drvdata(struct regulator *regulator,
+ void *data)
+{
+}
+
+#endif
+
+#endif
--
1.5.4.3



2008-03-08 03:43:30

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Thursday 06 March 2008, Liam Girdwood wrote:
> +static inline int uA_to_A(int uA) { return uA / 1000000; }

So: 999999 uA == 0A ... should DIV_ROUND_UP() or another
rounding function be involved in some of these conversions?

Or maybe the dividing conversions should not be provided, and
code should just be doing math in units that don't encourage
such problems to appear. I don't think one rounding policy
can fit all (including truncation, as above).


> +struct regulator *__must_check regulator_get(struct device *dev,
> +??????????????????????????????????????? ? ? const char *id);

The semantics of "id" and "dev" are unspecified in this patch,
so this isn't a good definition of the consumer interface!

Plus, that works more like a "lookup" than a "get" ... the
usual convention is that "get" and "put" update refcounts.
But I think I see an assumption here that a regulator may
have only one user...


> +int regulator_set_voltage(struct regulator *regulator, int uV);

You described a mode where consumers could set ranges that
might overlap (e.g. 1.6 to 1.9V, 1.8 to 2.0) and the result
would be some compatible result. But I don't see how that
could be achieved, since that's the only call to provide
a consumer's constraints.

Presumably one configures a voltage then enables it? How
does one turn a voltage supply on or off? I'm guessing
that zero volts doesn't equate to "off"...

Something that's lacking here is simple examples. Like: how
do I get the power supply associated with an MMC/SD card socket,
turn it on (to, say, 3V3), set it to supply a different voltage
(maybe 1V8), then turn it off? How would I cope with that
voltage supply being shared by two sockets, with cards that may
support different voltage ranges and have different current
requirements? (Configurations of interest include two cards
that can coexist at 1V8, and two that can't ... one might not
support 1V8, or it might demand too much power. Also, zero
and one cards present.)

- Dave

2008-03-09 11:11:12

by Liam Girdwood

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Fri, 2008-03-07 at 19:43 -0800, David Brownell wrote:
> On Thursday 06 March 2008, Liam Girdwood wrote:
> > +static inline int uA_to_A(int uA) { return uA / 1000000; }
>
> So: 999999 uA == 0A ... should DIV_ROUND_UP() or another
> rounding function be involved in some of these conversions?
>
> Or maybe the dividing conversions should not be provided, and
> code should just be doing math in units that don't encourage
> such problems to appear. I don't think one rounding policy
> can fit all (including truncation, as above).
>

ok, this sounds like the best approach.

>
> > +struct regulator *__must_check regulator_get(struct device *dev,
> > + const char *id);
>
> The semantics of "id" and "dev" are unspecified in this patch,
> so this isn't a good definition of the consumer interface!
>

'id' is really the regulator name and will be renamed in the next patch.

> Plus, that works more like a "lookup" than a "get" ... the
> usual convention is that "get" and "put" update refcounts.
> But I think I see an assumption here that a regulator may
> have only one user...

A regulator only has one user as it's used to store some device specific
power data. However, a regulator_dev has many users. I'll add a refcount
on get/put.

>
>
> > +int regulator_set_voltage(struct regulator *regulator, int uV);
>
> You described a mode where consumers could set ranges that
> might overlap (e.g. 1.6 to 1.9V, 1.8 to 2.0) and the result
> would be some compatible result. But I don't see how that
> could be achieved, since that's the only call to provide
> a consumer's constraints.

In this example the power domain constraint (not consumer constraint)
would be 1.6 - > 2.0 V. i.e. this range is safe for all consumers on
this domain as all can operate at 2.0V and some can operate as low as
1.6V.

The actual regulator output will be determined by consumer voltage
requests. e.g. On power domain A, consumer x sets 1.8V and consumer y
sets 1.9V, hence regulator output will be 1.9V. (as y needs 1.9 to
operate, but x can operate at 1.8 - 2.0)


>
> Presumably one configures a voltage then enables it? How
> does one turn a voltage supply on or off? I'm guessing
> that zero volts doesn't equate to "off"...

Some regulators cant go down as far as 0V ;)

We have regulator_enable() and regulator_disable() to turn on and off
regulator output.

e.g. set voltage -> enable -> do some stuff -> disable.

>
> Something that's lacking here is simple examples. Like: how
> do I get the power supply associated with an MMC/SD card socket,
> turn it on (to, say, 3V3), set it to supply a different voltage
> (maybe 1V8), then turn it off?

I have some examples in my git tree :-

backlight

http://opensource.wolfsonmicro.com/cgi-bin/gitweb.cgi?p=linux-2.6-audioplus.git;a=blob;f=drivers/video/backlight/wm8350_bl.c;h=ce79cf008b0e830be91c98fac0fb845efb767aa5;hb=imx31

LED's

http://opensource.wolfsonmicro.com/cgi-bin/gitweb.cgi?p=linux-2.6-audioplus.git;a=blob;f=drivers/leds/leds-wm8350.c;h=e46156439efd3f63e1bc0af9bc96fe6e855a22c2;hb=imx31

CPUfreq

http://opensource.wolfsonmicro.com/cgi-bin/gitweb.cgi?p=linux-2.6-audioplus.git;a=blob;f=arch/arm/mach-mx3/cpufreq.c;h=c6539737105c64b336cbb4f068b7ad20e918bca6;hb=imx31

Audio

http://opensource.wolfsonmicro.com/cgi-bin/gitweb.cgi?p=linux-2.6-audioplus.git;a=blob;f=sound/soc/imx/imx32ads-wm8350.c;h=4dcb3619e6152959f7d6f26e2febf1b0a688bf86;hb=imx31


In most cases we are passing the power supply name to the consumer
driver as platform data. e.g.

struct wm8350_led_platform_data wm8350_led_data = {
.name = "wm8350:white",
.default_trigger = "heartbeat",
.isink = WM8350_ISINK_A,
.dcdc = WM8350_DCDC_5,
.voltage_ramp = WM8350_DC5_RMP_20V,
.retries = 5,
.half_value = 9863,
.full_value = 27898,
};


> How would I cope with that
> voltage supply being shared by two sockets, with cards that may
> support different voltage ranges and have different current
> requirements? (Configurations of interest include two cards
> that can coexist at 1V8, and two that can't ... one might not
> support 1V8, or it might demand too much power. Also, zero
> and one cards present.)

In this case the MMC/SD power domain would be 1V8 to 3V3 and it would be
upto the MMC/SD driver to ensure it didn't over voltage a 1V8 card with
3V3 in this case. It would also be possible that the system designer
would assign each slot a separate regulator to provide max flexibility
in this case.

Liam

2008-03-11 02:07:57

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Sunday 09 March 2008, Liam Girdwood wrote:
>
> > > +struct regulator *__must_check regulator_get(struct device *dev,
> > > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?const char *id);
> >
> > The semantics of "id" and "dev" are unspecified in this patch,
> > so this isn't a good definition of the consumer interface!
> >
>
> 'id' is really the regulator name and will be renamed in the next patch.

Still not helping. How would a driver know what names to use?
Are those names globally scoped, or local to the device?

Again, "id" and "dev" are unspecified. I can maybe guess that
you're trying to make this look like <linux/clk.h> ... except
the clock API includes kernel doc in that header.

I *strongly* think new interfaces should not be provided without
documentation... but that's what this patch does.


> > Plus, that works more like a "lookup" than a "get" ... the
> > usual convention is that "get" and "put" update refcounts.
> > But I think I see an assumption here that a regulator may
> > have only one user...
>
> A regulator only has one user as it's used to store some device specific
> power data. However, a regulator_dev has many users. I'll add a refcount
> on get/put.

I'm still not following. If there's only one user, why would
you need refcounting? If your model here is the clock API,
then you should support multiple users ... and then refcounting
is very appropriate.

- Dave

2008-03-11 02:08:18

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Sunday 09 March 2008, Liam Girdwood wrote:
>
> > > +int regulator_set_voltage(struct regulator *regulator, int uV);
> >
> > You described a mode where consumers could set ranges that
> > might overlap (e.g. 1.6 to 1.9V, 1.8 to 2.0) and the result
> > would be some compatible result. ?But I don't see how that
> > could be achieved, since that's the only call to provide
> > a consumer's constraints.
>
> In this example the power domain constraint (not consumer constraint)
> would be 1.6 - > 2.0 V.

I was actually thinking of a chip I've used which has four
prgrammable regulators:

* Three are similar ... they can supply 2.5V, 2.75V, or
3.0V; plus a regulator-specific fourth setting of either
3.3V, 1.8V, or adjusted by board-specific feedback.

* The fourth has eight settings (from 0.85V up to 1.6V).

Those are the hard power domain constraints for the chip.

But any given board (set of "consumers") needs to be able to
provide additional constraints.


> i.e. this range is safe for all consumers on
> this domain as all can operate at 2.0V and some can operate as low as
> 1.6V.

You've declared similar hidden assumptions in response to some
of my other questions. Such hidden assumptions are not helpful.
Best to document them, if they survive discussion ...

One assumption is that consumers can't make constraints. That's
because of a second one, that somehow board designers can and will
ensure they don't need to.

I don't buy that. If the designer ensured that there would be
no need for such constraints, then why even have a set_voltage()
request? That adds a constraint ... but it's an inflexible one.


But maybe the broader issue is: just what model are you using
for customization here? At what points are constraints specific
to a chip, board, or external connection applied?


My assumption is that the regulators themselves should know
only about their hard constraints ... most often specific to
the chip (this regulator is optimized for these voltages),
but sometimes specific to a given board's wiring (e.g. the
resistor ladder for a given voltage feedback channel).

And then additional constraints could come from consumers,
which would basically be of two types: (a) board setup code,
and (b) drivers that cope with various situations, some of
which are externally imposed. Those drivers would tend to
need just on/off controls for power domains they manage,
but in some cases (like the MMC example I mentioned) would
need more capability than that.


> The actual regulator output will be determined by consumer voltage
> requests. e.g. On power domain A, consumer x sets 1.8V and consumer y
> sets 1.9V, hence regulator output will be 1.9V. (as y needs 1.9 to
> operate, but x can operate at 1.8 - 2.0)

So when consumer X tunes everything to run in a low power mode
(using 1.6V as a better example), consumer Y can come along and
change things (to 2.0V ... 25% higher voltage, a "huge" delta)?

How would consume X know that it's got to re-adjust things, and
shift out of a low power operational mode? Or prevent the need
to do that? (Or vice versa. Y could come first, preventing X
from entering a low power mode ... though maybe X could still
run in a high power mode.)


> > Presumably one configures a voltage then enables it? ?How
> > does one turn a voltage supply on or off? ?I'm guessing
> > that zero volts doesn't equate to "off"...
>
> Some regulators cant go down as far as 0V ;)

For the ones that can, shouldn't that be equivalent to disabling
the regulator? And for ones that can't, doesn't that mean
that regulator can not be enabled or disabled??

This "interface" definition is at best vague about quite a
lot of issues like these.


> We have regulator_enable() and regulator
> regulator output.
>
> e.g. set voltage -> enable -> do some stuff -> disable.

Would it be allowable to enable -> set voltage too?

Oh ... and if the regulator doesn't have a setting for
the specific voltage requested, is it allowed to choose
something "close"? (How close is close enough?) Or must
it instead fail?

- Dave

2008-03-11 10:20:55

by Liam Girdwood

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Mon, 2008-03-10 at 16:39 -0800, David Brownell wrote:
> On Sunday 09 March 2008, Liam Girdwood wrote:
> >
> > > > +struct regulator *__must_check regulator_get(struct device *dev,
> > > > + const char *id);
> > >
> > > The semantics of "id" and "dev" are unspecified in this patch,
> > > so this isn't a good definition of the consumer interface!
> > >
> >
> > 'id' is really the regulator name and will be renamed in the next patch.
>
> Still not helping. How would a driver know what names to use?

Platform data i.e. "WM8350-DCDC1". The links I gave in a previous mail
have examples for this wrt LED. Backlight drivers.

> Are those names globally scoped, or local to the device?
>

They are global.

> Again, "id" and "dev" are unspecified. I can maybe guess that
> you're trying to make this look like <linux/clk.h> ... except
> the clock API includes kernel doc in that header.
>
> I *strongly* think new interfaces should not be provided without
> documentation... but that's what this patch does.
>

Fair point, I'll add docs for v4.

>
> > > Plus, that works more like a "lookup" than a "get" ... the
> > > usual convention is that "get" and "put" update refcounts.
> > > But I think I see an assumption here that a regulator may
> > > have only one user...
> >
> > A regulator only has one user as it's used to store some device specific
> > power data. However, a regulator_dev has many users. I'll add a refcount
> > on get/put.
>
> I'm still not following. If there's only one user, why would
> you need refcounting? If your model here is the clock API,
> then you should support multiple users ... and then refcounting
> is very appropriate.
>

Maybe the naming is confusing here. We should probably rename regulator
to regulator_client or similar.

Liam

2008-03-11 15:19:46

by Liam Girdwood

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Mon, 2008-03-10 at 18:00 -0800, David Brownell wrote:
> On Sunday 09 March 2008, Liam Girdwood wrote:
> >
> > > > +int regulator_set_voltage(struct regulator *regulator, int uV);
> > >
> > > You described a mode where consumers could set ranges that
> > > might overlap (e.g. 1.6 to 1.9V, 1.8 to 2.0) and the result
> > > would be some compatible result. But I don't see how that
> > > could be achieved, since that's the only call to provide
> > > a consumer's constraints.
> >
> > In this example the power domain constraint (not consumer constraint)
> > would be 1.6 - > 2.0 V.
>
> I was actually thinking of a chip I've used which has four
> prgrammable regulators:
>
> * Three are similar ... they can supply 2.5V, 2.75V, or
> 3.0V; plus a regulator-specific fourth setting of either
> 3.3V, 1.8V, or adjusted by board-specific feedback.
>
> * The fourth has eight settings (from 0.85V up to 1.6V).
>
> Those are the hard power domain constraints for the chip.
>
> But any given board (set of "consumers") needs to be able to
> provide additional constraints.

I think we probably have some confusion over the nomenclature here (as
there are several 'levels' of constraint). I'll detail this in the docs
though.

I think you are meaning the board (or power domain) constraint here:-

The regulator driver currently enforces the chip (or regulator)
constraints, whilst the power domain (board) constraints are defined in
board.c.

e.g.

struct regulation_constraints led = {
.min_uA = 0,
.max_uA = 27898,
.valid_ops_mask = REGULATOR_CHANGE_CURRENT,
.valid_modes_mask = REGULATOR_MODE_NORMAL,
};

struct regulation_constraints cpufreq = {
.min_uV = mV_to_uV(1300),
.max_uV = mV_to_uV(1600),
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
.valid_modes_mask = REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST,
};

It designed to work as follows:-

1. Consumer: set voltage 1.8V
2. reg core: if 1.8V is not within board (power domain) constraint then
return err.
3. regulator (chip) driver: check that 1.8V is ok then write to chip to
change voltage.

>
>
> > i.e. this range is safe for all consumers on
> > this domain as all can operate at 2.0V and some can operate as low as
> > 1.6V.
>
> You've declared similar hidden assumptions in response to some
> of my other questions. Such hidden assumptions are not helpful.
> Best to document them, if they survive discussion ...
>
> One assumption is that consumers can't make constraints. That's
> because of a second one, that somehow board designers can and will
> ensure they don't need to.
>

A board designer must make sure that the power domain constraints are
within the regulator (chip) constraints. He must also make sure that all
consumers on a power domain can all operate similtaiously at the same
voltage and that they are not damaged by other domain consumers
operating at different voltages.

> I don't buy that. If the designer ensured that there would be
> no need for such constraints, then why even have a set_voltage()
> request? That adds a constraint ... but it's an inflexible one.
>

Basically there are two types of consumers.

1. Consumers that don't care about their supply voltage/current. They
use the voltage specified by the system designer and don't care about
it's value. They only need to enable()/disable()

2. Consumers that do care about their voltage/current. This group of
consumers do care about voltage and current. Typical users are
Backlight, CPUfreq, LED's, MMC, vibrator, USB.....

The first type can usually share a supply regulator whilst the latter
group have a 1:1 consumer to regulator mapping.

The system designer ensures that all type 1 consumers exist on domains
with compatible power requirements. Type 1 consumers don't care about
voltage or current constraints.

Type 2 consumers do care about power domain constraints.

This also leads to 3 different types of power domain :-

1. Fixed Voltage.
2. Variable Voltage.
3. Variable Current limit.

>
> But maybe the broader issue is: just what model are you using
> for customization here? At what points are constraints specific
> to a chip, board, or external connection applied?
>

We have the physical constraints of the regulators (chip) and the
physical constraints of the power domain. The power domain example near
the top hopefully answers this.

>
> My assumption is that the regulators themselves should know
> only about their hard constraints

Agreed, they do.

> ... most often specific to
> the chip (this regulator is optimized for these voltages),
> but sometimes specific to a given board's wiring (e.g. the
> resistor ladder for a given voltage feedback channel).
>

Imho, the regulator driver should not no anything about the board. It's
up to the board init code to configure things like this.

We do this atm for a WM8350 resistor config in platform code and pass
onto the pmic driver.

> And then additional constraints could come from consumers,
> which would basically be of two types: (a) board setup code,
> and (b) drivers that cope with various situations, some of
> which are externally imposed. Those drivers would tend to
> need just on/off controls for power domains they manage,
> but in some cases (like the MMC example I mentioned) would
> need more capability than that.
>
>
> > The actual regulator output will be determined by consumer voltage
> > requests. e.g. On power domain A, consumer x sets 1.8V and consumer y
> > sets 1.9V, hence regulator output will be 1.9V. (as y needs 1.9 to
> > operate, but x can operate at 1.8 - 2.0)
>
> So when consumer X tunes everything to run in a low power mode
> (using 1.6V as a better example), consumer Y can come along and
> change things (to 2.0V ... 25% higher voltage, a "huge" delta)?

This is probably a bad example as the voltage delta is quite large and
probably unrealistic. I was thinking of smaller deltas in the range of a
few percent. The big numbers just make it easier to read. I'm beginning
to consider removing this feature.

>
> How would consume X know that it's got to re-adjust things, and
> shift out of a low power operational mode? Or prevent the need
> to do that? (Or vice versa. Y could come first, preventing X
> from entering a low power mode ... though maybe X could still
> run in a high power mode.)
>

We have a notifier block for notifying changes atm but it doesn't notify
other domain consumers of a pending domain voltage change yet.

>
> > > Presumably one configures a voltage then enables it? How
> > > does one turn a voltage supply on or off? I'm guessing
> > > that zero volts doesn't equate to "off"...
> >
> > Some regulators cant go down as far as 0V ;)
>
> For the ones that can, shouldn't that be equivalent to disabling
> the regulator?

Imho no, as the regulator internals will probably still be clocking and
burning power when set to 0V. I think we need the enable() and disable()
calls to do make this cleaner.

> And for ones that can't, doesn't that mean
> that regulator can not be enabled or disabled??
>
> This "interface" definition is at best vague about quite a
> lot of issues like these.
>
>
> > We have regulator_enable() and regulator
> > regulator output.
> >
> > e.g. set voltage -> enable -> do some stuff -> disable.
>
> Would it be allowable to enable -> set voltage too?
>

Yes, this is fine.

> Oh ... and if the regulator doesn't have a setting for
> the specific voltage requested, is it allowed to choose
> something "close"? (How close is close enough?) Or must
> it instead fail?
>

It should fail. However, it might be worth adding something like :-

regulator_set_voltage(client, min, max);
regulator_set_current(client, min, max);

I think it's probably best that I write some docs describing the
architecture and usage model before any more patches. Hopefully, this
will clear up the ambiguities around constraints and nomenclature. I'll
also factor in the recent comments in this email chain.

Liam

2008-03-11 21:40:29

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Tuesday 11 March 2008, Liam Girdwood wrote:
> On Mon, 2008-03-10 at 16:39 -0800, David Brownell wrote:
> > On Sunday 09 March 2008, Liam Girdwood wrote:
> > >
> > > > > +struct regulator *__must_check regulator_get(struct device *dev,
> > > > > + const char *id);
> > > >
> > > > The semantics of "id" and "dev" are unspecified in this patch,
> > > > so this isn't a good definition of the consumer interface!
> > >
> > > 'id' is really the regulator name and will be renamed in the next patch.
> >
> > Still not helping. How would a driver know what names to use?
>
> Platform data i.e. "WM8350-DCDC1". The links I gave in a previous mail
> have examples for this wrt LED. Backlight drivers.

I looked at some of that code a while back and didn't find them
all that informative. Probably because implementations can be
interpreted in many ways, and I'm trying to understand which
concepts you intend to promote here...


> > Are those names globally scoped, or local to the device?
> >
>
> They are global.

So it's somewhat unlike the clock API then ... enough that I'd
reconsider *why* it's different. The clock API allows both
global names and locally scoped ones.

Surely it would be better to just let device drivers call
something like

client = regulator_lookup(dev, "Vcc");

and have the board setup code bind the right regulator to
that name for a given device? It could work same way that
platform devices use logically numbered (or sometimes, named)
resources for register memory and IRQs, and the way the clock
framework uses logical names for device clocks.

Example: all USART controllers may use the same logical
clock name "usart", instead of global names like "usart0_clk",
"usart1_clk", "mck", etc (as appropriate). In the same way,
"Vcc" could be a local name for various devices ... where
the global name might be board-specific like "WM8350-DCDC1".


I suspect I'm walking towards a notion of a "power domain"
here, which would of course be fed by a regulator but would
be explicitly shared by multiple devices. That's a notion
which has come up before in power management discussions, as
needing some explicit support by the Linux PM framwork. It
applies both inside modern PM-aware SOCs, and at the board
level. (It feels to me like you've focussed so far on the
latter.)

How would you see your notion of a "regulator" (client?)
relating to a "power domain"? My first thought is that
there's a one-to-one correspondence but they may not be
quite the same thing. Example, one might want to ask the
domain what devices it supports ... so that you could ask
them all to power off.

- Dave

2008-03-11 22:25:23

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Tuesday 11 March 2008, David Brownell wrote:
> How would you see your notion of a "regulator" (client?)
> relating to a "power domain"? ?My first thought is that
> there's a one-to-one correspondence but they may not be
> quite the same thing. ?Example, one might want to ask the
> domain what devices it supports ... so that you could ask
> them all to power off.

Actually, it's clearly not one-to-one. Counter-example:
a 3V3 regulator powering one of a SOC's I/O power domains,
which is managed by a digital switch. That same regulator
can power several I/O devices too. It may even feed a 1V8
regulator.

So the relationship is probably that regulators define a
domain ... but such domains can be subdivided. There's
a tree; it's probably more shallow than the clock tree.

And enable/disable primitives probably map best to power
domains, not all of which are entire regulators.

- Dave

2008-03-12 00:15:08

by Mark Brown

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Tue, Mar 11, 2008 at 02:25:10PM -0800, David Brownell wrote:
> On Tuesday 11 March 2008, David Brownell wrote:

> > How would you see your notion of a "regulator" (client?)
> > relating to a "power domain"? ?My first thought is that
> > there's a one-to-one correspondence but they may not be

> Actually, it's clearly not one-to-one. Counter-example:
> a 3V3 regulator powering one of a SOC's I/O power domains,
> which is managed by a digital switch. That same regulator
> can power several I/O devices too. It may even feed a 1V8
> regulator.

It's also common for devices to have multiple power inputs which can be
run separately if required but which are normally tied together unless
there is a special reason to do so.

> So the relationship is probably that regulators define a
> domain ... but such domains can be subdivided. There's
> a tree; it's probably more shallow than the clock tree.

This is pretty much the model that is currently implemented. A given
power management IC can have several regulators (that is, things which
have regulator IDs registered and can supply power). Each regulator can
have multiple clients bound to it (that is, things that have called
regulator_get() and can consume power). It is also possible to tell the
core that one regulator supplies another - if this is done then the core
will take care of ensuring that parents are enabled when their children
need them.

> And enable/disable primitives probably map best to power
> domains, not all of which are entire regulators.

While the leaf enable/disable operations do happen at the client level
the core reference counts the enabled clients to control enabling of the
actual supply.

2008-03-12 06:30:18

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Tuesday 11 March 2008, Liam Girdwood wrote:
> On Mon, 2008-03-10 at 18:00 -0800, David Brownell wrote:
> > On Sunday 09 March 2008, Liam Girdwood wrote:
> > >
> > > > > +int regulator_set_voltage(struct regulator *regulator, int uV);
> > > >
> > > > You described a mode where consumers could set ranges that
> > > > might overlap (e.g. 1.6 to 1.9V, 1.8 to 2.0) and the result
> > > > would be some compatible result. But I don't see how that
> > > > could be achieved, since that's the only call to provide
> > > > a consumer's constraints.
> > >
> > > In this example the power domain constraint (not consumer constraint)
> > > would be 1.6 - > 2.0 V.
> >
> > I was actually thinking of a chip I've used which has four
> > prgrammable regulators:
> >
> > * Three are similar ... they can supply 2.5V, 2.75V, or
> > 3.0V; plus a regulator-specific fourth setting of either
> > 3.3V, 1.8V, or adjusted by board-specific feedback.
> >
> > * The fourth has eight settings (from 0.85V up to 1.6V).
> >
> > Those are the hard power domain constraints for the chip.
> >
> > But any given board (set of "consumers") needs to be able to
> > provide additional constraints.
>
> I think we probably have some confusion over the nomenclature here (as
> there are several 'levels' of constraint). I'll detail this in the docs
> though.
>
> I think you are meaning the board (or power domain) constraint here:-

I named two different sets of constraints. One from the power
management chips themselves. And a board-specific subset of those;
which just limits the power supply capabilities that drivers could
access. In a way, each constraint defines a subsidiary domain...


> The regulator driver currently enforces the chip (or regulator)
> constraints, whilst the power domain (board) constraints are defined in
> board.c.

OK -- that's the right model. Drivers are generic, and board
specific stuff is localized in board.c files.


> It designed to work as follows:-
>
> 1. Consumer: set voltage 1.8V

Now you're introducing a third party, adding its own constraints.
In this case: something that must be a subset of the constraints
you've defined already.


> 2. reg core: if 1.8V is not within board (power domain) constraint then
> return err.
> 3. regulator (chip) driver: check that 1.8V is ok then write to chip to
> change voltage.

If the only way to add constraints is to add new layers, I think
there will be some undesirable API growth patterns. :)

This is handled in the clock framework just as part of the clock
tree. Drivers mostly deal only with leaves and a few branches.
Platform and board code deals with the rest: this board has
these crystals, these PLLs are configured as follows, divisors
set like this, maybe autogated in hardware, etc.

I'd think that a power domain tree would be a natural model to
use here, and it would avoid those API growth troubles...


> A board designer must make sure that the power domain constraints are
> within the regulator (chip) constraints.

Right.


> He must also make sure that all
> consumers on a power domain can all operate similtaiously at the same
> voltage

That may of course require the drivers to know which voltage
has been chosen, and to be able to rule out some voltages.

I think changing voltages will be uncommon outside of board
specific setup code, at least for now. Hardware designers
aren't currently expecting software to be able to dynamically
adjust voltage, for power saving or whatever. Except for
DVFS stuff like cpufreq, which is awkward since among other
things it's got to coordinate clock and power domain changes.

But we already have one example in-kernel of a simple driver
framework which supports switching just voltages at run-time...

That's the MMC framework. As a rule all MMC/SD cards can
work at 3/3.3V, plus or minus a few decivolts. But there's
been a push to get "dual voltage" cards out there, which can
also operate at 1.8V (plus or minus, in a smaller range).
See <include/mmc/mmc_host.h> for the MMC_VDD bitmasks; the
architecture allows ranges that aren't yet widely used by
current boards and cards.


> and that they are not damaged by other domain consumers
> operating at different voltages.

If a board supports two MMC slots, it could easily end up
having a "high" voltage card and a dual voltage card inserted
at the same time, sharing the same regulator. That may mean
the low voltage range is temporarily not allowable. It's
an issue of "can it work", not "will it be damaged".


> > I don't buy that. If the designer ensured that there would be
> > no need for such constraints, then why even have a set_voltage()
> > request? That adds a constraint ... but it's an inflexible one.
> >
>
> Basically there are two types of consumers.
>
> 1. Consumers that don't care about their supply voltage/current. They
> use the voltage specified by the system designer and don't care about
> it's value. They only need to enable()/disable()

They want an on/off switch, basically. Though I think there
are variants of this, notably:

- Some drivers don't really need to know if power goes off.
They can share a power domain, and are content with a
refcount model: turn it off when no users are active.

- Other drivers may care that it's actually off; maybe the
only reset mechanism they have is a power-up reset, or
they need to power down a saw to change its blade.

Some of that will be supported by the hardware designs. But
when it's not, I think a "power it down NOW!" primitive may
be needed. Folk managing industrial controls will probably
need extra features -- it takes time for the voltage/current
to stop, the saw blade has momentum, etc -- but minimally it
seems to me there should be a "disable-and-wait" variant for
drivers in that second category.


> 2. Consumers that do care about their voltage/current. This group of
> consumers do care about voltage and current. Typical users are
> Backlight, CPUfreq, LED's, MMC, vibrator, USB.....

Some LCD contrast controls run by voltage too.

USB has fairly limited current control requirements; in
practice they matter more on the peripheral side, where
the host supplies a certain amount of current (at nominal
5V), which is a system *input* ...

I hesitate to call this second class of driver "power aware".
The driver has a control knob it uses, and it doesn't know
what goes on when it turns that knob. MMC and USB are to
some extent truly power aware: labels on those knobs read
Volts (MMC) and current (MMC, nyet supported; and USB).
Even CPUfreq just uses presets for its DVFS settings.


> The first type can usually share a supply regulator whilst the latter
> group have a 1:1 consumer to regulator mapping.
>
> The system designer ensures that all type 1 consumers exist on domains
> with compatible power requirements. Type 1 consumers don't care about
> voltage or current constraints.

To the extent that's true, I suspect it's because hardware
designers have been told software won't manage power budgets.

On the other hand, I can easily imagine wanting to do something
like have a 150 mA regulator power a couple MMC slots, instead
of a 300 mA one, and just require that software not kick in
high power read/writes in both slots at the same time. That's
just a simple current budgeting issue, which may not matter until
someone puts two high speed/power cards in at once...


> Type 2 consumers do care about power domain constraints.
>
> This also leads to 3 different types of power domain :-
>
> 1. Fixed Voltage.
> 2. Variable Voltage.
> 3. Variable Current limit.

I think that conclusion doesn't quite follow from what you've
said so far. But I'm not sure it matters, at least for what
I've needed to do.


> > But maybe the broader issue is: just what model are you using
> > for customization here? At what points are constraints specific
> > to a chip, board, or external connection applied?
> >
>
> We have the physical constraints of the regulators (chip) and the
> physical constraints of the power domain. The power domain example near
> the top hopefully answers this.

It's a bit clearer, but you're introducing a new term
"power domain", and your understanding of that notion
doesn't quite match what I've seen. It may be a lot
simpler to represent the hierarchy of power domains,
not unlike how the hierarchy of clock domains.


> > My assumption is that the regulators themselves should know
> > only about their hard constraints
>
> Agreed, they do.
>
> > ... most often specific to
> > the chip (this regulator is optimized for these voltages),
> > but sometimes specific to a given board's wiring (e.g. the
> > resistor ladder for a given voltage feedback channel).
>
> Imho, the regulator driver should not no anything about the board. It's
> up to the board init code to configure things like this.
>
> We do this atm for a WM8350 resistor config in platform code and pass
> onto the pmic driver.

That's what device.platform_data should be used for. It's not
a case of drivers hard-wiring board-specific data; they should
get told such stuff the same way other drivers get told.

Remember that board init code probably can't do anything with
that resistor config; knowledge of how to do that shuld be part
of a driver that hasn't yet initialized.


> > And then additional constraints could come from consumers,
> > which would basically be of two types: (a) board setup code,
> > and (b) drivers that cope with various situations, some of
> > which are externally imposed. Those drivers would tend to
> > need just on/off controls for power domains they manage,
> > but in some cases (like the MMC example I mentioned) would
> > need more capability than that.
> >
> >
> > > The actual regulator output will be determined by consumer voltage
> > > requests. e.g. On power domain A, consumer x sets 1.8V and consumer y
> > > sets 1.9V, hence regulator output will be 1.9V. (as y needs 1.9 to
> > > operate, but x can operate at 1.8 - 2.0)
> >
> > So when consumer X tunes everything to run in a low power mode
> > (using 1.6V as a better example), consumer Y can come along and
> > change things (to 2.0V ... 25% higher voltage, a "huge" delta)?
>
> This is probably a bad example as the voltage delta is quite large and
> probably unrealistic. I was thinking of smaller deltas in the range of a
> few percent. The big numbers just make it easier to read. I'm beginning
> to consider removing this feature.

I chose my MMC example with care. :)

And in that case, it's very realistic to want to put a slot
into either a 3V3 or 1V8 regulation mode. It's also realistic
to have slots share a parent power domain (and thus a current
budget), even if they have individual FETs for power on/off.
The stretch is small: that both situations are combined.


> > How would consume X know that it's got to re-adjust things, and
> > shift out of a low power operational mode? Or prevent the need
> > to do that? (Or vice versa. Y could come first, preventing X
> > from entering a low power mode ... though maybe X could still
> > run in a high power mode.)
> >
>
> We have a notifier block for notifying changes atm but it doesn't notify
> other domain consumers of a pending domain voltage change yet.

Maybe the notifier should be per-domain, with veto capability.
That would address the issues I noted. Though it should be a
bit simpler to just have the clients register callbacks if
they care; notifiers are an idiom that mostly bothers me.


> > > > Presumably one configures a voltage then enables it? How
> > > > does one turn a voltage supply on or off? I'm guessing
> > > > that zero volts doesn't equate to "off"...
> > >
> > > Some regulators cant go down as far as 0V ;)
> >
> > For the ones that can, shouldn't that be equivalent to disabling
> > the regulator?
>
> Imho no, as the regulator internals will probably still be clocking and
> burning power when set to 0V. I think we need the enable() and disable()
> calls to do make this cleaner.

I'm not sure I see the point in *not* expecting the
regulator to turn itself off when set to 0V ... but
that's not a very big issue.


> > And for ones that can't, doesn't that mean
> > that regulator can not be enabled or disabled??
> >
> > This "interface" definition is at best vague about quite a
> > lot of issues like these.
> >
> >
> > > We have regulator_enable() and regulator
> > > regulator output.
> > >
> > > e.g. set voltage -> enable -> do some stuff -> disable.
> >
> > Would it be allowable to enable -> set voltage too?
> >
>
> Yes, this is fine.

Something for kerneldoc to make clear.


> > Oh ... and if the regulator doesn't have a setting for
> > the specific voltage requested, is it allowed to choose
> > something "close"? (How close is close enough?) Or must
> > it instead fail?
> >
>
> It should fail. However, it might be worth adding something like :-
>
> regulator_set_voltage(client, min, max);
> regulator_set_current(client, min, max);

That make sense to me. More so than needing to worry about
whether 3.1V will pass as 3.0V on a given system...


> I think it's probably best that I write some docs describing the
> architecture and usage model before any more patches. Hopefully, this
> will clear up the ambiguities around constraints and nomenclature. I'll
> also factor in the recent comments in this email chain.

Agreed. In particular, please consider the notion of a tree
of power domains, as a way to cleanly structure all the various
interdependencies.

- Dave

2008-03-12 07:32:19

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Tuesday 11 March 2008, Mark Brown wrote:
> On Tue, Mar 11, 2008 at 02:25:10PM -0800, David Brownell wrote:
> > On Tuesday 11 March 2008, David Brownell wrote:
>
> > > How would you see your notion of a "regulator" (client?)
> > > relating to a "power domain"? ?My first thought is that
> > > there's a one-to-one correspondence but they may not be
>
> > Actually, it's clearly not one-to-one. Counter-example:
> > a 3V3 regulator powering one of a SOC's I/O power domains,
> > which is managed by a digital switch. That same regulator
> > can power several I/O devices too. It may even feed a 1V8
> > regulator.
>
> It's also common for devices to have multiple power inputs which can be
> run separately if required but which are normally tied together unless
> there is a special reason to do so.

I've not happened across that idiom. Is that common on
particular larger systems?


> > So the relationship is probably that regulators define a
> > domain ... but such domains can be subdivided. There's
> > a tree; it's probably more shallow than the clock tree.
>
> This is pretty much the model that is currently implemented.

Then the tree should be a bit more of a first class citizen,
IMO, like it is in the clock framework. Both clock and power
distribution have similar hardware infrastructure; the software
interfaces can be more similar than it is.


> A given
> power management IC can have several regulators (that is, things which
> have regulator IDs registered and can supply power).

Those are the outputs. Are the inputs visible? Like batteries
or loosely regulated DC voltages ... drivers/power/* stuff.


> Each regulator can
> have multiple clients bound to it (that is, things that have called
> regulator_get() and can consume power).

In the clock framework, clk_get_parent() exposes one part of this
relationship. But there's also the association of logical clock
names to devices ...


> It is also possible to tell the
> core that one regulator supplies another - if this is done then the core
> will take care of ensuring that parents are enabled when their children
> need them.

Right. clk_enable()/clk_disable() uses a refcounting model for
that stuff; similar.


> > And enable/disable primitives probably map best to power
> > domains, not all of which are entire regulators.
>
> While the leaf enable/disable operations do happen at the client level
> the core reference counts the enabled clients to control enabling of the
> actual supply.

Right. But what I was getting at was that there can be
domains hooked up like:

Power --> Regulator -+-> Switch-1 -+-> Switch-2 --> [Dev-A]
| |
| +-> [Dev-B], [Dev-C]
|
+-> [Dev-D], [Dev-E]

That is: five power domains, one regulator:

- Input power, e.g. a battery
- Regulator output, maybe configurable
- Devices D and E share a domain coupled to the regulator
- Devices B and C share a switched domain
- Device A has its own switched domain

Those switches can be as simple as a MOSFET under GPIO control.

And I'd expect power domains under Linux to be able to represent
all of those ... including software controls wherevever they're
practical, which in this case might include everything except the
battery input.

- Dave

2008-03-12 13:02:26

by Mark Brown

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Tue, Mar 11, 2008 at 11:31:59PM -0800, David Brownell wrote:
> On Tuesday 11 March 2008, Mark Brown wrote:

> > It's also common for devices to have multiple power inputs which can be
> > run separately if required but which are normally tied together unless
> > there is a special reason to do so.

> I've not happened across that idiom. Is that common on
> particular larger systems?

It's standard on the analogue side of audio codecs, for example.

> > This is pretty much the model that is currently implemented.

> Then the tree should be a bit more of a first class citizen,
> IMO, like it is in the clock framework. Both clock and power
> distribution have similar hardware infrastructure; the software
> interfaces can be more similar than it is.

What do you see as being missing in the externally presented interface?
As far as I can see the main difference between the two APIs on this
front is that the regulator API explicitly separates the interface used
to set up the tree from the interface used by consumers.

> > A given
> > power management IC can have several regulators (that is, things which
> > have regulator IDs registered and can supply power).

> Those are the outputs. Are the inputs visible? Like batteries
> or loosely regulated DC voltages ... drivers/power/* stuff.

Not as part of this API at present unless the input is another
regulator, though obviously drivers could set up associations in the
device tree.

> > Each regulator can
> > have multiple clients bound to it (that is, things that have called
> > regulator_get() and can consume power).

> In the clock framework, clk_get_parent() exposes one part of this
> relationship. But there's also the association of logical clock
> names to devices ...

Right, though that does tend to break down when clocks go off chip - the
association of devices with symbolic names is generally only done for
things that are hard wired as part of the same chip since the devices
are registered along with the clock. Other clocks generally just get
the name that the chip documents for them. Indeed, looking around the
tree almost all current use of clock API appears to be for on-SoC devices.

Unless I'm missing something the obvious way to provide off-chip
symbolic names in the clock API is for board code to register a virtual
clock with the desired name and device and parent it off the actual
clock source. That said I can't immediately find any actual uses of that
and at least some of the implementations I've seen wouldn't support it.
A similar approach should work here, though I'm not sure it's terribly
nice.

What might be nicer would be an API that platform code could use to map
regulators to device/name tuples. The core could then search these when
a client calls regulator_get() (either by maintaining a separate table
or by setting up virtual regulators).

> > While the leaf enable/disable operations do happen at the client level
> > the core reference counts the enabled clients to control enabling of the
> > actual supply.

> Right. But what I was getting at was that there can be
> domains hooked up like:

> Power --> Regulator -+-> Switch-1 -+-> Switch-2 --> [Dev-A]
> | |
> | +-> [Dev-B], [Dev-C]
> |
> +-> [Dev-D], [Dev-E]

> Those switches can be as simple as a MOSFET under GPIO control.

> And I'd expect power domains under Linux to be able to represent
> all of those ... including software controls wherevever they're
> practical, which in this case might include everything except the
> battery input.

I don't see a particular problem fitting this into the structure of
the current API - to me the switches inflexible regulators with no
configurable voltage control of their own. The core would need to be
enhanced a bit to cope with passing through the configurability of the
parent regulator when a child has no get/set operations of its own but
that doesn't need to be visible to anything except the non-configurable
regulators.

2008-03-12 21:53:01

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Wednesday 12 March 2008, Mark Brown wrote:
> On Tue, Mar 11, 2008 at 11:31:59PM -0800, David Brownell wrote:

> > > This is pretty much the model that is currently implemented.
>
> > Then the tree should be a bit more of a first class citizen,
> > IMO, like it is in the clock framework. Both clock and power
> > distribution have similar hardware infrastructure; the software
> > interfaces can be more similar than it is.
>
> What do you see as being missing in the externally presented interface?

It's not *presented* as a tree of power domains, and it's not clear
that's the intended model. Plus, what Liam said about the names
being global, not local/logical.


> As far as I can see the main difference between the two APIs on this
> front is that the regulator API explicitly separates the interface used
> to set up the tree from the interface used by consumers.

I'd say that differently. The clock framework *has* no such
implementor/setup support ... which has caused problems for
many new implementations. I'm unclear on the status of some
recent patches [1] from Dmitry Baryshkov to help address that.


> > > A given
> > > power management IC can have several regulators (that is, things which
> > > have regulator IDs registered and can supply power).
>
> > Those are the outputs. Are the inputs visible? Like batteries
> > or loosely regulated DC voltages ... drivers/power/* stuff.
>
> Not as part of this API at present unless the input is another
> regulator, though obviously drivers could set up associations in the
> device tree.

That may not be an issue; it's something which can be provided
by a PMIC driver, in any case. If they both catch on, maybe
some integration will become useful.


> > > Each regulator can
> > > have multiple clients bound to it (that is, things that have called
> > > regulator_get() and can consume power).
>
> > In the clock framework, clk_get_parent() exposes one part of this
> > relationship. But there's also the association of logical clock
> > names to devices ...
>
> Right, though that does tend to break down when clocks go off chip - the
> association of devices with symbolic names is generally only done for
> things that are hard wired as part of the same chip since the devices
> are registered along with the clock. Other clocks generally just get
> the name that the chip documents for them. Indeed, looking around the
> tree almost all current use of clock API appears to be for on-SoC devices.

That's because there's essentially no way to plug in other clocks
in an arch-neutral way ... so the only implementations of clocks
are arch-specific!! This is at least partly addressed by [1], but
platforms would also need to adopt that implementation framework.
So far the only patches showing that are on PXA and SA-1100, which
hardly present challenges in that area ... compared to e.g. OMAP.

Specifically, it's awkard even to do simple things like binding
one of a SOC's programmable clocks onto an off-chip audio codec
or video controller; that's got to go through platform_data or
something similar. And plugging in external clock generators ...
not portably, no way!

You seem to be aiming to not recreate those problems, which is good.


> What might be nicer would be an API that platform code could use to map
> regulators to device/name tuples. The core could then search these when
> a client calls regulator_get() (either by maintaining a separate table
> or by setting up virtual regulators).

Right.


> > > While the leaf enable/disable operations do happen at the client level
> > > the core reference counts the enabled clients to control enabling of the
> > > actual supply.
>
> > Right. But what I was getting at was that there can be
> > domains hooked up like:
>
> > Power --> Regulator -+-> Switch-1 -+-> Switch-2 --> [Dev-A]
> > | |
> > | +-> [Dev-B], [Dev-C]
> > |
> > +-> [Dev-D], [Dev-E]
>
> > Those switches can be as simple as a MOSFET under GPIO control.
>
> > And I'd expect power domains under Linux to be able to represent
> > all of those ... including software controls wherevever they're
> > practical, which in this case might include everything except the
> > battery input.
>
> I don't see a particular problem fitting this into the structure of
> the current API - to me the switches inflexible regulators with no
> configurable voltage control of their own.

To me, they aren't regulators at all. :)

I see power domains as having various capabilities. Most of them
support on/off switching ... else there's no reason to list them
(except for the root nodes of the tree). Some are programmable,
and suppport configuring the voltage or current drive.

That maps exactly to the clock tree model. Not all clocks can
support clk_set_rate() or clk_set_parent(). Not all power domains
can support a set_voltage() call, etc.

This just suggests a bit of refocusing of your current code,
so it'll be more widely applicable.

- Dave

[1] http://marc.info/?l=linux-kernel&m=120237673527430&w=2
http://marc.info/?l=linux-kernel&m=120237674327434&w=2

2008-03-12 23:26:19

by Ian molton

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface


On Wed, 2008-03-12 at 13:52 -0800, David Brownell wrote:
> > I don't see a particular problem fitting this into the structure of
> > the current API - to me the switches inflexible regulators with no
> > configurable voltage control of their own.
>
> To me, they aren't regulators at all. :)

I dunno.

Regulate - to control.

A switch certainly controls voltage. Admittedly the granularity is a
little coarser than a nice digitally controlled regulator, but it fits
the model...

2008-03-12 23:57:26

by Mark Brown

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Wed, Mar 12, 2008 at 01:52:46PM -0800, David Brownell wrote:
> On Wednesday 12 March 2008, Mark Brown wrote:

> > What do you see as being missing in the externally presented interface?

> It's not *presented* as a tree of power domains, and it's not clear
> that's the intended model. Plus, what Liam said about the names
> being global, not local/logical.

Hrm. I suspect that the documentation which Liam is currently writing
(together with some actual in-tree users) will help here.

> > As far as I can see the main difference between the two APIs on this
> > front is that the regulator API explicitly separates the interface used
> > to set up the tree from the interface used by consumers.

> I'd say that differently. The clock framework *has* no such
> implementor/setup support ... which has caused problems for

Well, the platforms I've looked at do implement a fairly standard
registration API to set up their clocks, even if it's only used to
configure things for the particular SoC variant in use and does tend to
omit things not used on the platform in question.

> many new implementations. I'm unclear on the status of some
> recent patches [1] from Dmitry Baryshkov to help address that.

That looks like it'd help a lot in making the feature set implemented by
the clock API consistent over platforms.

> Specifically, it's awkard even to do simple things like binding
> one of a SOC's programmable clocks onto an off-chip audio codec
> or video controller; that's got to go through platform_data or
> something similar. And plugging in external clock generators ...
> not portably, no way!

> You seem to be aiming to not recreate those problems, which is good.

Right; any regulator API is going to need to cope with connecting
multiple chips together since that's such a core use case.

> > What might be nicer would be an API that platform code could use to map
> > regulators to device/name tuples. The core could then search these when
> > a client calls regulator_get() (either by maintaining a separate table
> > or by setting up virtual regulators).

> Right.

We'll try to implement this before we next resubmit.

> > > Power --> Regulator -+-> Switch-1 -+-> Switch-2 --> [Dev-A]
> > > | |
> > > | +-> [Dev-B], [Dev-C]
> > > |
> > > +-> [Dev-D], [Dev-E]

> > I don't see a particular problem fitting this into the structure of
> > the current API - to me the switches inflexible regulators with no
> > configurable voltage control of their own.

...

> That maps exactly to the clock tree model. Not all clocks can
> support clk_set_rate() or clk_set_parent(). Not all power domains
> can support a set_voltage() call, etc.

That's the aim, and some of this works already. For example, regulators
with no set_voltage() are supported by the core.

> This just suggests a bit of refocusing of your current code,
> so it'll be more widely applicable.

In API terms I'm not sure it even needs a refocusing - I think the API
can already support everything you're asking for in this subthread
except for the addition of an API to allow platforms to map a symbolic
name and device tuple to an actual regulator. Some of the cases that
can be set up will require additional work in the core to support them
but doing that shouldn't affect anything that doesn't directly deal with
those cases.

2008-03-13 05:10:26

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Wednesday 12 March 2008, ian wrote:
> >
> > To me, they aren't regulators at all. ?:)
>
> I dunno.
>
> Regulate - to control.
>
> A switch certainly controls voltage.

You could stretch the terminology that way, yes.


> Admittedly the granularity is a
> little coarser than a nice digitally controlled regulator, but it fits
> the model...

Yet if you go into a parts catalog, you'll see that regulators
and switches (low side, high side, etc) are different parts.
Also, that many (most?) regulators aren't switchable.

Given my druthers, there'd be no repurposing of common terms
like "switch" and "regulator". That's all I'm getting at; in
normal usage, they are two different things. (And what we
care about is their output -- a power domain, possibly shared,
possibly somewhat controllable -- not how it works.)

- Dave

2008-03-13 05:11:18

by David Brownell

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Wednesday 12 March 2008, Mark Brown wrote:
> On Wed, Mar 12, 2008 at 01:52:46PM -0800, David Brownell wrote:
> > On Wednesday 12 March 2008, Mark Brown wrote:
>
> > > What do you see as being missing in the externally presented interface?
>
> > It's not *presented* as a tree of power domains, and it's not clear
> > that's the intended model. Plus, what Liam said about the names
> > being global, not local/logical.
>
> Hrm. I suspect that the documentation which Liam is currently writing
> (together with some actual in-tree users) will help here.

Yes, code is only one part of a balanced architecture.
It's pretty weak at conveying any "big picture" issues,
especially with only one underlying implementation. If
I can't get that picture without reviewing 100+ KBytes
of code, then something critical is missing...

I've been pushing for clear explanations in part because,
well, nobody else has. I've come across clear needs for
basic power switching, to manage sections of both SOCs and
boards; and less clear needs for voltage adjustment. I've
been hoping some of the other folk who have looked at these
issues would chime in.

- Dave


> Right; any regulator API is going to need to cope with connecting
> multiple chips together since that's such a core use case.

2008-03-13 12:01:06

by Mark Brown

[permalink] [raw]
Subject: Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface

On Wed, Mar 12, 2008 at 09:08:48PM -0800, David Brownell wrote:
> On Wednesday 12 March 2008, Mark Brown wrote:

> > Hrm. I suspect that the documentation which Liam is currently writing
> > (together with some actual in-tree users) will help here.

> Yes, code is only one part of a balanced architecture.
> It's pretty weak at conveying any "big picture" issues,
> especially with only one underlying implementation. If
> I can't get that picture without reviewing 100+ KBytes
> of code, then something critical is missing...

OK, that's good - from what you were saying it sounded like you had some
more fundamental objection. Users are probably at least as important as
text documentation here since it's them that people tend to look at when
they need to look at code. As with a lot of things the core isn't the
best thing to look at since it has to care about the things that it is
abstracting away from users.

> I've been pushing for clear explanations in part because,
> well, nobody else has. I've come across clear needs for
> basic power switching, to manage sections of both SOCs and
> boards; and less clear needs for voltage adjustment. I've
> been hoping some of the other folk who have looked at these
> issues would chime in.

The ability to adjust voltage is required for devices like MMC and CPU
frequency control so it needs to be implemented to at least some degree
and if we do it for everything it reduces the number of special cases to
handle. Systems that don't need or want it can disable it by setting an
exact constraint in the platform code at which point it decays into a
safety feature.