* [UPDATED v3][PATCH 1/7] regulator: consumer interface @ 2008-03-06 18:10 Liam Girdwood 2008-03-08 3:43 ` David Brownell 0 siblings, 1 reply; 19+ messages in thread From: Liam Girdwood @ 2008-03-06 18:10 UTC (permalink / raw) To: Andrew Morton; +Cc: linux-arm-kernel, linux-kernel, Mark Brown 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 <lg@opensource.wolfsonmicro.com> --- 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 <lg@opensource.wolfsonmicro.com> + * + * 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 ^ permalink raw reply related [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-06 18:10 [UPDATED v3][PATCH 1/7] regulator: consumer interface Liam Girdwood @ 2008-03-08 3:43 ` David Brownell 2008-03-09 11:10 ` Liam Girdwood 0 siblings, 1 reply; 19+ messages in thread From: David Brownell @ 2008-03-08 3:43 UTC (permalink / raw) To: Liam Girdwood; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-08 3:43 ` David Brownell @ 2008-03-09 11:10 ` Liam Girdwood 2008-03-11 0:39 ` David Brownell 2008-03-11 2:00 ` David Brownell 0 siblings, 2 replies; 19+ messages in thread From: Liam Girdwood @ 2008-03-09 11:10 UTC (permalink / raw) To: David Brownell; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-09 11:10 ` Liam Girdwood @ 2008-03-11 0:39 ` David Brownell 2008-03-11 10:20 ` Liam Girdwood 2008-03-11 2:00 ` David Brownell 1 sibling, 1 reply; 19+ messages in thread From: David Brownell @ 2008-03-11 0:39 UTC (permalink / raw) To: Liam Girdwood; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-11 0:39 ` David Brownell @ 2008-03-11 10:20 ` Liam Girdwood 2008-03-11 21:36 ` David Brownell 0 siblings, 1 reply; 19+ messages in thread From: Liam Girdwood @ 2008-03-11 10:20 UTC (permalink / raw) To: David Brownell; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel, Mark Brown 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-11 10:20 ` Liam Girdwood @ 2008-03-11 21:36 ` David Brownell 2008-03-11 22:25 ` David Brownell 0 siblings, 1 reply; 19+ messages in thread From: David Brownell @ 2008-03-11 21:36 UTC (permalink / raw) To: Liam Girdwood; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel, Mark Brown 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-11 21:36 ` David Brownell @ 2008-03-11 22:25 ` David Brownell 2008-03-12 0:00 ` Mark Brown 0 siblings, 1 reply; 19+ messages in thread From: David Brownell @ 2008-03-11 22:25 UTC (permalink / raw) To: Liam Girdwood; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-11 22:25 ` David Brownell @ 2008-03-12 0:00 ` Mark Brown 2008-03-12 7:31 ` David Brownell 0 siblings, 1 reply; 19+ messages in thread From: Mark Brown @ 2008-03-12 0:00 UTC (permalink / raw) To: David Brownell Cc: Liam Girdwood, Andrew Morton, linux-arm-kernel, linux-kernel 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. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-12 0:00 ` Mark Brown @ 2008-03-12 7:31 ` David Brownell 2008-03-12 13:02 ` Mark Brown 0 siblings, 1 reply; 19+ messages in thread From: David Brownell @ 2008-03-12 7:31 UTC (permalink / raw) To: Mark Brown; +Cc: Liam Girdwood, Andrew Morton, linux-arm-kernel, linux-kernel 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-12 7:31 ` David Brownell @ 2008-03-12 13:02 ` Mark Brown 2008-03-12 21:52 ` David Brownell 0 siblings, 1 reply; 19+ messages in thread From: Mark Brown @ 2008-03-12 13:02 UTC (permalink / raw) To: David Brownell Cc: Liam Girdwood, Andrew Morton, linux-arm-kernel, linux-kernel 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. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-12 13:02 ` Mark Brown @ 2008-03-12 21:52 ` David Brownell 2008-03-12 23:26 ` ian 2008-03-12 23:57 ` Mark Brown 0 siblings, 2 replies; 19+ messages in thread From: David Brownell @ 2008-03-12 21:52 UTC (permalink / raw) To: Mark Brown Cc: Liam Girdwood, Andrew Morton, linux-arm-kernel, linux-kernel, Dmitry Baryshkov 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-12 21:52 ` David Brownell @ 2008-03-12 23:26 ` ian 2008-03-13 4:39 ` David Brownell 2008-03-12 23:57 ` Mark Brown 1 sibling, 1 reply; 19+ messages in thread From: ian @ 2008-03-12 23:26 UTC (permalink / raw) To: David Brownell Cc: Mark Brown, Dmitry Baryshkov, Andrew Morton, linux-arm-kernel, linux-kernel 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... ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-12 23:26 ` ian @ 2008-03-13 4:39 ` David Brownell 0 siblings, 0 replies; 19+ messages in thread From: David Brownell @ 2008-03-13 4:39 UTC (permalink / raw) To: ian; +Cc: Mark Brown, Andrew Morton, linux-arm-kernel, linux-kernel 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-12 21:52 ` David Brownell 2008-03-12 23:26 ` ian @ 2008-03-12 23:57 ` Mark Brown 2008-03-13 5:08 ` David Brownell 1 sibling, 1 reply; 19+ messages in thread From: Mark Brown @ 2008-03-12 23:57 UTC (permalink / raw) To: David Brownell Cc: Liam Girdwood, Andrew Morton, linux-arm-kernel, linux-kernel, Dmitry Baryshkov 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. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-12 23:57 ` Mark Brown @ 2008-03-13 5:08 ` David Brownell 2008-03-13 12:00 ` Mark Brown 0 siblings, 1 reply; 19+ messages in thread From: David Brownell @ 2008-03-13 5:08 UTC (permalink / raw) To: Mark Brown Cc: Liam Girdwood, Andrew Morton, linux-arm-kernel, linux-kernel, Dmitry Baryshkov 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. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-13 5:08 ` David Brownell @ 2008-03-13 12:00 ` Mark Brown 0 siblings, 0 replies; 19+ messages in thread From: Mark Brown @ 2008-03-13 12:00 UTC (permalink / raw) To: David Brownell Cc: Liam Girdwood, Andrew Morton, linux-arm-kernel, linux-kernel, Dmitry Baryshkov 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. ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-09 11:10 ` Liam Girdwood 2008-03-11 0:39 ` David Brownell @ 2008-03-11 2:00 ` David Brownell 2008-03-11 15:19 ` Liam Girdwood 1 sibling, 1 reply; 19+ messages in thread From: David Brownell @ 2008-03-11 2:00 UTC (permalink / raw) To: Liam Girdwood; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-11 2:00 ` David Brownell @ 2008-03-11 15:19 ` Liam Girdwood 2008-03-12 6:29 ` David Brownell 0 siblings, 1 reply; 19+ messages in thread From: Liam Girdwood @ 2008-03-11 15:19 UTC (permalink / raw) To: David Brownell; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel, Mark Brown 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [UPDATED v3][PATCH 1/7] regulator: consumer interface 2008-03-11 15:19 ` Liam Girdwood @ 2008-03-12 6:29 ` David Brownell 0 siblings, 0 replies; 19+ messages in thread From: David Brownell @ 2008-03-12 6:29 UTC (permalink / raw) To: Liam Girdwood; +Cc: linux-arm-kernel, Andrew Morton, linux-kernel, Mark Brown 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 ^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2008-03-13 12:01 UTC | newest] Thread overview: 19+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2008-03-06 18:10 [UPDATED v3][PATCH 1/7] regulator: consumer interface Liam Girdwood 2008-03-08 3:43 ` David Brownell 2008-03-09 11:10 ` Liam Girdwood 2008-03-11 0:39 ` David Brownell 2008-03-11 10:20 ` Liam Girdwood 2008-03-11 21:36 ` David Brownell 2008-03-11 22:25 ` David Brownell 2008-03-12 0:00 ` Mark Brown 2008-03-12 7:31 ` David Brownell 2008-03-12 13:02 ` Mark Brown 2008-03-12 21:52 ` David Brownell 2008-03-12 23:26 ` ian 2008-03-13 4:39 ` David Brownell 2008-03-12 23:57 ` Mark Brown 2008-03-13 5:08 ` David Brownell 2008-03-13 12:00 ` Mark Brown 2008-03-11 2:00 ` David Brownell 2008-03-11 15:19 ` Liam Girdwood 2008-03-12 6:29 ` David Brownell
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox